XMLSerialize: version and explicit XML declaration
Hi,
I'm working on the flags VERSION (X076), INCLUDING XMLDECLARATION, and
EXCLUDING XMLDECLARATION (X078) for XMLSerialize, and I have a question
for SQL/XML experts on the list.
Is there any validation mechanism for VERSION <character string
literal>? The SQL/XML spec says
"The <character string literal> immediately contained in <XML serialize
version> shall be '1.0' or '1.1', or it shall identify some successor to
XML 1.0 and XML 1.1."
I was wondering if a validation here would make any sense, since
XMLSerialize is only supposed to print a string --- not to mention that
validating "some successor to XML 1.0 and XML 1.1" can be challenging :)
But again, printing an "invalid" XML string also doesn't seem very nice.
The oracle implementation accepts pretty much anything:
SQL> SELECT xmlserialize(DOCUMENT xmltype('<foo><bar>42</bar></foo>')
VERSION 'foo') AS xml FROM dual;
XML
--------------------------------------------------------------------------------
<?xml version="foo"?>
<foo>
<bar>42</bar>
</foo>
In db2, anything other than '1.0' raises an error:
db2 => SELECT XMLSERIALIZE(CONTENT XMLELEMENT(NAME "db2",service_level)
AS varchar(100) VERSION '1.0' INCLUDING XMLDECLARATION) FROM
sysibmadm.env_inst_info;
1
----------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?><db2>DB2
v11.5.9.0</db2>
1 record(s) selected.
db2 => SELECT XMLSERIALIZE(CONTENT XMLELEMENT(NAME "db2",service_level)
AS varchar(100) VERSION '1.1' INCLUDING XMLDECLARATION) FROM
sysibmadm.env_inst_info;
SQL0171N The statement was not processed because the data type, length or
value of the argument for the parameter in position "2" of routine
"XMLSERIALIZE" is incorrect. Parameter name: "". SQLSTATE=42815
Any thoughts on how we should approach this feature?
Thanks!
Best, Jim
Jim Jones <jim.jones@uni-muenster.de> writes:
Is there any validation mechanism for VERSION <character string
literal>?
AFAICS, all we do with an embedded XML version string is pass it to
libxml2's xmlNewDoc(), which is the authority on whether it means
anything. I'd be inclined to do the same here.
regards, tom lane
Hi Tom
On 25.09.24 18:02, Tom Lane wrote:
AFAICS, all we do with an embedded XML version string is pass it to
libxml2's xmlNewDoc(), which is the authority on whether it means
anything. I'd be inclined to do the same here.
Thanks. I used xml_is_document(), which calls xmlNewDoc(), to check if
the returned document is valid or not. It then decides if an unexpected
version deserves an error or just a warning.
Attached v1 with the first attempt to implement these features.
==== INCLUDING / EXCLUDING XMLDECLARATION (SQL/XML X078) ====
The flags INCLUDING XMLDECLARATION and EXCLUDING XMLDECLARATION include
or remove the XML declaration in the XMLSerialize output of the given
DOCUMENT or CONTENT, respectively.
SELECT
xmlserialize(
DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text
INCLUDING XMLDECLARATION);
xmlserialize
---------------------------------------------------------------
<?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
(1 row)
SELECT
xmlserialize(
DOCUMENT '<?xml version="1.0"
encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text
EXCLUDING XMLDECLARATION);
xmlserialize
--------------------------
<foo><bar>42</bar></foo>
(1 row)
If omitted, the output will contain an XML declaration only if the given
XML value had one.
SELECT
xmlserialize(
DOCUMENT '<?xml version="1.0"
encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text);
xmlserialize
----------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>
(1 row)
SELECT
xmlserialize(
DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text);
xmlserialize
--------------------------
<foo><bar>42</bar></foo>
(1 row)
==== VERSION (SQL/XML X076)====
VERSION can be used to specify the version in the XML declaration of the
serialized DOCUMENT or CONTENT.
SELECT
xmlserialize(
DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
xmlserialize
---------------------------------------------------------------
<?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
(1 row)
In case of XML values of type DOCUMENT, the version will be validated by
libxml2's xmlNewDoc(), which will raise an error for invalid
versions or a warning for unsupported ones. For CONTENT values no
validation is performed.
SELECT
xmlserialize(
DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text
VERSION '1.1'
INCLUDING XMLDECLARATION);
WARNING: line 1: Unsupported version '1.1'
<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
^
xmlserialize
---------------------------------------------------------------
<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
(1 row)
SELECT
xmlserialize(
DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text
VERSION '2.0'
INCLUDING XMLDECLARATION);
ERROR: Invalid XML declaration: VERSION '2.0'
SELECT
xmlserialize(
CONTENT '<foo><bar>42</bar></foo>'::xml AS text
VERSION '2.0'
INCLUDING XMLDECLARATION);
xmlserialize
---------------------------------------------------------------
<?xml version="2.0" encoding="UTF8"?><foo><bar>42</bar></foo>
(1 row)
This option is ignored if the XML value had no XML declaration and
INCLUDING XMLDECLARATION was not used.
SELECT
xmlserialize(
CONTENT '<foo><bar>42</bar></foo>'::xml AS text
VERSION '1111');
xmlserialize
--------------------------
<foo><bar>42</bar></foo>
(1 row)
Best, Jim
Attachments:
v1-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v1-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From 8bcb91f8b163a9efda1de33ebb7538767c860ad9 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Thu, 26 Sep 2024 13:35:28 +0200
Subject: [PATCH v1] Add XMLSerialize: version and explicit XML declaration
* XMLSerialize: explicit XML declaration (SQL/XML X078)
This adds the options INCLUDING XMLDECLARATION and EXCLUDING
XMLDECLARATION to XMLSerialize, which includes or remove the
XML declaration of the given DOCUMENT or CONTENT, respectively.
If not specified, the output will contain an XML declaration
only if the given XML value had one.
* XMLSerialize: version (SQL/XML X076)
The option VERSION can be used to specify the version in the
XML declaration of the serialized DOCUMENT or CONTENT. In case
of XML values of type DOCUMENT, the version will be validated
by libxml2's xmlNewDoc(), which will raise an error for invalid
versions or a warning for unsupported ones. For CONTENT values
no validation is performed. This option is ignored if the XML
value had no XML deldaration and INCLUDING XMLDECLARATION was
not used.
Usage examples:
SELECT
xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT
xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 48 ++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/xml.c | 119 +++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 428 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 275 +++++++++++++++++
src/test/regress/expected/xml_2.out | 401 ++++++++++++++++++++++++
src/test/regress/sql/xml.sql | 72 +++++
14 files changed, 1347 insertions(+), 52 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index e0d33f12e1..3c81ff57e5 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4496,7 +4496,7 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ VERSION <replaceable>xmlversion</replaceable> ] [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ] [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4506,6 +4506,22 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The option <literal>VERSION</literal> can be used to specify
+ the version in <replaceable>xmlversion</replaceable> as the
+ version in the XML declaration. If <literal>NULL</literal>
+ the version <literal>1.0</literal> is assumed.
+ </para>
+
+ <para>
+ The options <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> specify whether the
+ XML declaration of an XML <replaceable>value</replaceable> is
+ included in the serialized string or not, respectively. If not
+ specified, the output will only contain an XML delcaration if
+ the XML <replaceable>value</replaceable> had one.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4513,6 +4529,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index c002f37202..6e6be85126 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 9fd988cc99..332901a1d1 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4189,7 +4189,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b1d4642c59..4d210ce904 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -625,6 +625,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -793,8 +795,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -15930,14 +15932,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16162,6 +16166,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -17853,6 +17872,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18508,6 +18528,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 36c1b7a88f..b74823ccb2 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2491,6 +2491,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 040a896263..9d261fceea 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -153,7 +153,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -326,7 +327,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -598,7 +599,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -653,7 +655,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -666,7 +669,9 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
PgXmlErrorContext *xmlerrcxt;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -697,8 +702,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -721,18 +730,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
/* Detect whether there's an XML declaration */
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
- /*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ /* Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -754,7 +760,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* content nodes, and then iterate over the nodes.
*/
xmlNodePtr root;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -772,19 +778,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -798,7 +809,37 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * We add the XML declaration if the input had one or if the flag
+ * INCLUDING XMLDECLARATION was used.
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ StringInfoData xmldecl;
+ initStringInfo(&xmldecl);
+
+ print_xml_decl(
+ &xmldecl,
+ xmlserialize_version != NULL ? (const xmlChar *) xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char*) doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used, otherwise
+ * XML declaration and root element will be serialized in the same
+ * line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ xmlBufferAddHead(buf, (const xmlChar *) xmldecl.data, xmldecl.len);
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -845,6 +886,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("Invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1084,7 +1137,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1589,14 +1642,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1605,7 +1664,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index e62ce1b753..f573a0a8c5 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -848,6 +848,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index ea47652adb..d3c7212c65 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1593,6 +1593,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1615,6 +1622,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 899d64ad55..40baf38220 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -504,6 +504,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index ed20e21375..248d22971a 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 361a6f9b27..c56c1d16bc 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index d26e10441e..979388ab1b 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index 73c2851d3f..c0f2d33cad 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: Invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index f752ecb142..91fe599eef 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
--
2.34.1
On 30.09.24 10:08, Jim Jones wrote:
On 25.09.24 18:02, Tom Lane wrote:
AFAICS, all we do with an embedded XML version string is pass it to
libxml2's xmlNewDoc(), which is the authority on whether it means
anything. I'd be inclined to do the same here.Thanks. I used xml_is_document(), which calls xmlNewDoc(), to check if
the returned document is valid or not. It then decides if an unexpected
version deserves an error or just a warning.Attached v1 with the first attempt to implement these features.
rebase
Best regards, Jim
Attachments:
v2-0001-Add-XMLSerialize-explicit-XML-declaration-SQL-XML.patchtext/x-patch; charset=UTF-8; name=v2-0001-Add-XMLSerialize-explicit-XML-declaration-SQL-XML.patchDownload
From adfc1b9137ac8b004fe9e495fb79f2bf4b21cf49 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Fri, 21 Feb 2025 10:10:40 +0100
Subject: [PATCH v2] Add XMLSerialize: explicit XML declaration (SQL/XML X078)
This adds the options INCLUDING XMLDECLARATION and EXCLUDING
XMLDECLARATION to XMLSerialize, which include or remove the
XML declaration of a given DOCUMENT or CONTENT, respectively.
SELECT
xmlserialize(DOCUMENT val AS text INCLUDING XMLDECLARATION);
SELECT
xmlserialize(DOCUMENT val AS text EXCLUDING XMLDECLARATION);
If not specified, the output will contain an XML declaration or
not depending on the given XML value. This patch also includes
regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 34 ++++-
src/backend/catalog/sql_features.txt | 2 +-
src/backend/executor/execExprInterp.c | 3 +-
src/backend/parser/gram.y | 15 +-
src/backend/parser/parse_expr.c | 1 +
src/backend/utils/adt/ruleutils.c | 5 +
src/backend/utils/adt/xml.c | 91 ++++++++---
src/include/nodes/parsenodes.h | 1 +
src/include/nodes/primnodes.h | 9 ++
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 2 +-
src/test/regress/expected/xml.out | 208 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 154 +++++++++++++++++++
src/test/regress/expected/xml_2.out | 208 +++++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 36 +++++
15 files changed, 738 insertions(+), 32 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 87679dc4a1..b9b84cda45 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4511,7 +4511,7 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] [INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4528,6 +4528,38 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+ The options <type>INCLUDING XMLDECLARATION</type> and <type>EXCLUDING XMLDECLARATION</type> specify
+ whether the XML declaration of an XML <replaceable>value</replaceable> is included in the serialized string or not, respectively.
+ If not specified, the output will only contain an XML delcaration if the XML <replaceable>value</replaceable> had one.
+ </para>
+
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo><bar>42</bar></foo> +
+
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo> +
+
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>+
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index 2f250d2c57..c9b9e5e0f0 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -667,7 +667,7 @@ X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
X076 XMLSerialize: VERSION NO
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 1c3477b03c..91d3352bb9 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4540,7 +4540,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7d99c9355c..024015f088 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -620,6 +620,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -788,8 +789,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16079,7 +16080,7 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option opt_xml_declaration_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
@@ -16087,6 +16088,7 @@ func_expr_common_subexpr:
n->expr = $4;
n->typeName = $6;
n->indent = $7;
+ n->xmldeclaration = $8;
n->location = @1;
$$ = (Node *) n;
}
@@ -16311,6 +16313,11 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18006,6 +18013,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18663,6 +18671,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index bad1df732e..3b5c35a79b 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2489,6 +2489,7 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index d11a8a20ee..8bd6536b95 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10150,6 +10150,11 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfoString(buf, " INDENT");
else
appendStringInfoString(buf, " NO INDENT");
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
}
if (xexpr->op == IS_DOCUMENT)
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index db8d0d6a7e..97ccd64802 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -653,7 +653,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -666,7 +667,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
PgXmlErrorContext *xmlerrcxt;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION && !indent)
{
/*
* We don't actually need to do anything, so just return the
@@ -697,8 +699,11 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide or show the
+ * xml declaration, we're done.
+ */
+ if (!indent && xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -722,17 +727,22 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
- */
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION. Indent the buffer content
+ * if the flag INDENT was used. Note: some versions of xmlSaveToBuffer
+ * leak memory if a non-null encoding argument is passed, so don't do
+ * that. We don't want any encoding conversion anyway.
+ */
+ ctxt = xmlSaveToBuffer(buf, NULL,
+ /* remove XML declaration if EXCLUDING XMLDECLARATION was used. */
+ (xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION ? XML_SAVE_NO_DECL : 0) |
+ /*
+ * remove XML declaration if the xml string didn't have one and
+ * INCLUDING XMLDECLARATION was not used
+ */
+ ((decl_len == 0 && xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION) ? XML_SAVE_NO_DECL : 0) |
+ /* indent the xml dump if INDENT was used */
+ (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -754,7 +764,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* content nodes, and then iterate over the nodes.
*/
xmlNodePtr root;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -772,15 +782,19 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
@@ -792,13 +806,44 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
if (xmlSaveTree(ctxt, node) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save content to xmlBuffer");
}
}
- xmlFreeNode(newline);
+ /*
+ * If the flag INCLUDING XMLDECLARATION is specified, we have
+ * to manually add the XML declaration here. xmlSaveTree() does
+ * not include it.
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ {
+ StringInfoData xmldecl;
+ initStringInfo(&xmldecl);
+ appendStringInfoString(&xmldecl, "<?xml");
+
+ if (doc->version)
+ appendStringInfo(&xmldecl, " version=\"%s\"", doc->version);
+
+ if (doc->encoding)
+ appendStringInfo(&xmldecl, " encoding=\"%s\"", doc->encoding);
+
+ /* We only add "standalone" if the input's XML declaration had one */
+ if (doc->standalone == 1)
+ appendStringInfo(&xmldecl, " standalone=\"yes\"");
+ else if (doc->standalone == 0)
+ appendStringInfo(&xmldecl, " standalone=\"no\"");
+
+ appendStringInfoString(&xmldecl, "?>\n");
+ xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len);
+
+ pfree(xmldecl.data);
+ }
+
+ if (newline != NULL)
+ xmlFreeNode(newline);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 0b208f51bd..7661de3f5e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -857,6 +857,7 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 839e71d52f..5d46f8364b 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1598,6 +1598,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1620,6 +1627,8 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 40cf090ce6..7bfabfb147 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -506,6 +506,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f..748bf7bc17 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,7 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index bcc743f485..812eebb376 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -676,6 +676,200 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,6 +1018,12 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent including xmldeclaration);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent excluding xmldeclaration);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent including xmldeclaration);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent excluding xmldeclaration);
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
@@ -831,6 +1031,12 @@ SELECT table_name, view_definition FROM information_schema.views
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
@@ -840,7 +1046,7 @@ SELECT table_name, view_definition FROM information_schema.views
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(17 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index a1c5d31417..d887011165 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,130 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +717,36 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index 045641dae6..f3938b410f 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,200 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------
+ <?xml version="1.0" encoding="UTF-8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,6 +1004,12 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent including xmldeclaration);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent excluding xmldeclaration);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent including xmldeclaration);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent excluding xmldeclaration);
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
@@ -817,6 +1017,12 @@ SELECT table_name, view_definition FROM information_schema.views
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT INCLUDING XMLDECLARATION) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text NO INDENT EXCLUDING XMLDECLARATION) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
@@ -826,7 +1032,7 @@ SELECT table_name, view_definition FROM information_schema.views
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(17 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 4c3520ce89..56aa4317a6 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,35 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INDENT INCLUDING XMLDECLARATION);
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +250,13 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent including xmldeclaration);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent excluding xmldeclaration);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent including xmldeclaration);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text no indent excluding xmldeclaration);
+
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.34.1
rebase
Best, Jim
Attachments:
v3-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v3-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From 2b684d290cf4d3690e98ca9719af615d137237c8 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Fri, 23 May 2025 08:59:51 +0200
Subject: [PATCH v3] Add XMLSerialize: version and explicit XML declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Explicit XML declaration (SQL/XML:2023, X078)
This patch adds the options INCLUDING XMLDECLARATION and
EXCLUDING XMLDECLARATION to XMLSERIALIZE, allowing users
to explicitly control the presence of the XML declaration
(e.g., <?xml version="1.0" encoding="UTF-8"?>) in the
serialized output of XML values. If neither option is
specified, the output includes the declaration only if the
input XML value already contained one.
* Version support (SQL/XML:2023, X076)
The VERSION option allows specifying the version string
to use in the XML declaration. If specified, the version
must conform to the lexical rules of the XML standard,
e.g., '1.0' or '1.1'. If omitted or NULL, version '1.0'
is assumed.
In DOCUMENT mode, the version string is validated by
libxml2’s `xmlNewDoc()`, which will raise an error for
invalid versions and a warning for unsupported ones.
No validation is performed in CONTENT mode. This option
has no effect unless INCLUDING XMLDECLARATION is also
specified or the input XML value already contains a
declaration.
Examples:
SELECT xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 66 +++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/ruleutils.c | 9 +
src/backend/utils/adt/xml.c | 122 +++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 454 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 320 ++++++++++++++++++
src/test/regress/expected/xml_2.out | 427 +++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 81 +++++
15 files changed, 1476 insertions(+), 59 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 09309ba039..e06d19e930 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4520,7 +4520,7 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ VERSION <replaceable>xmlversion</replaceable> ] [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ] [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4530,6 +4530,40 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The <literal>VERSION</literal> option sets the version string
+ used in the XML declaration. If specified, the value of
+ <replaceable>xmlversion</replaceable> must conform to the lexical
+ rules of the XML standard: it must be a string of the form
+ <literal>'1.'</literal> followed by one or more digits (e.g.,
+ <literal>'1.0'</literal>, <literal>'1.1'</literal>). Versions other
+ than 1.x (e.g., <literal>'2.0'</literal>) are not valid in
+ <literal>DOCUMENT</literal> mode and will result in an error. This format
+ is defined in section 2.8,
+ <ulink url="https://www.w3.org/TR/xml/#sec-prolog-dtd">"Prolog and Document Type Declaration"</ulink>,
+ of the XML standard. If the <literal>VERSION</literal> option is omitted or specified as
+ <literal>NULL</literal>, version <literal>1.0</literal> is used by default.
+
+ In <literal>CONTENT</literal> mode, no validation is performed on the version,
+ and it is emitted as specified if an XML declaration is requested.
+ </para>
+
+ <para>
+ The <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> options control
+ whether the serialized output includes an XML declaration such as
+ <literal><?xml version="1.0" encoding="UTF-8"?></literal>.
+ If neither option is specified, the presence of the declaration in
+ the output depends on whether the input <replaceable>value</replaceable>
+ originally contained one.
+
+ The <literal>INCLUDING XMLDECLARATION</literal> option is allowed in both
+ <literal>DOCUMENT</literal> and <literal>CONTENT</literal> modes. In
+ <literal>CONTENT</literal> mode, no structural validation is performed,
+ and the declaration is emitted according to the specified options,
+ even if it would not normally be considered valid by the XML specification.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4537,6 +4571,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index ebe85337c2..999845fdeb 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 8a72b5e70a..0fa2fae281 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4621,7 +4621,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 0b5652071d..868aa6ca38 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -620,6 +620,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -788,8 +790,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16109,14 +16111,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16341,6 +16345,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18037,6 +18056,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18695,6 +18715,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 1f8e2d5467..efb4828a5f 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2497,6 +2497,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3d6e6bdbfd..080d772f6e 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10208,6 +10208,15 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfo(buf, " AS %s",
format_type_with_typemod(xexpr->type,
xexpr->typmod));
+
+ if (xexpr->version)
+ appendStringInfo(buf, " VERSION '%s'", xexpr->version);
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
+
if (xexpr->indent)
appendStringInfoString(buf, " INDENT");
else
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index a4150bff2e..79d02db947 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -153,7 +153,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -326,7 +327,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -598,7 +599,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -653,7 +655,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -666,7 +669,9 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
PgXmlErrorContext *xmlerrcxt;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -697,8 +702,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -722,17 +731,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ * Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -755,7 +762,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
*/
xmlNodePtr root;
xmlNodePtr oldroot;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -779,19 +786,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -805,7 +817,41 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION (X078, SQL/XML:2023).
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ StringInfoData xmldecl;
+ initStringInfo(&xmldecl);
+
+ print_xml_decl(
+ &xmldecl,
+ /*
+ * Use version from VERSION option (X076, SQL/XML:2023)
+ * if specified, otherwise use the document's version.
+ */
+ xmlserialize_version != NULL ? (const xmlChar *)xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char *)doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used,
+ * otherwise XML declaration and root element will be
+ * serialized in the same line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len);
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -852,6 +898,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1091,7 +1149,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1596,14 +1654,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1612,7 +1676,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 4610fc6129..b1916baef3 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -857,6 +857,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 7d3b4198f2..b8d76d8755 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1598,6 +1598,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1620,6 +1627,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index a4af3f717a..cf2cf74838 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -507,6 +507,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f..a79bda7d38 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 103a22a3b1..4557277e8a 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,23 +1226,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 73c411118a..236a07a1ba 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +868,51 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index a85d95358d..30ec649f33 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,23 +1211,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 0ea4f50883..e12683353e 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +293,15 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.34.1
rebase and add missing check for xmlBufferAddHead result
--
Jim
Attachments:
v4-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v4-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From 9f363be9fc18eeed8c96134466058a4f80a169f6 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Tue, 10 Jun 2025 12:27:32 +0200
Subject: [PATCH v4] Add XMLSerialize: version and explicit XML declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Explicit XML declaration (SQL/XML:2023, X078)
This patch adds the options INCLUDING XMLDECLARATION and
EXCLUDING XMLDECLARATION to XMLSERIALIZE, allowing users
to explicitly control the presence of the XML declaration
(e.g., <?xml version="1.0" encoding="UTF-8"?>) in the
serialized output of XML values. If neither option is
specified, the output includes the declaration only if the
input XML value already contained one.
* Version support (SQL/XML:2023, X076)
The VERSION option allows specifying the version string
to use in the XML declaration. If specified, the version
must conform to the lexical rules of the XML standard,
e.g., '1.0' or '1.1'. If omitted or NULL, version '1.0'
is assumed.
In DOCUMENT mode, the version string is validated by
libxml2’s `xmlNewDoc()`, which will raise an error for
invalid versions and a warning for unsupported ones.
No validation is performed in CONTENT mode. This option
has no effect unless INCLUDING XMLDECLARATION is also
specified or the input XML value already contains a
declaration.
Examples:
SELECT xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 66 +++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/ruleutils.c | 9 +
src/backend/utils/adt/xml.c | 133 ++++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 454 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 320 ++++++++++++++++++
src/test/regress/expected/xml_2.out | 427 +++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 81 +++++
15 files changed, 1487 insertions(+), 59 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 09309ba039..e06d19e930 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4520,7 +4520,7 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ VERSION <replaceable>xmlversion</replaceable> ] [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ] [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4530,6 +4530,40 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The <literal>VERSION</literal> option sets the version string
+ used in the XML declaration. If specified, the value of
+ <replaceable>xmlversion</replaceable> must conform to the lexical
+ rules of the XML standard: it must be a string of the form
+ <literal>'1.'</literal> followed by one or more digits (e.g.,
+ <literal>'1.0'</literal>, <literal>'1.1'</literal>). Versions other
+ than 1.x (e.g., <literal>'2.0'</literal>) are not valid in
+ <literal>DOCUMENT</literal> mode and will result in an error. This format
+ is defined in section 2.8,
+ <ulink url="https://www.w3.org/TR/xml/#sec-prolog-dtd">"Prolog and Document Type Declaration"</ulink>,
+ of the XML standard. If the <literal>VERSION</literal> option is omitted or specified as
+ <literal>NULL</literal>, version <literal>1.0</literal> is used by default.
+
+ In <literal>CONTENT</literal> mode, no validation is performed on the version,
+ and it is emitted as specified if an XML declaration is requested.
+ </para>
+
+ <para>
+ The <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> options control
+ whether the serialized output includes an XML declaration such as
+ <literal><?xml version="1.0" encoding="UTF-8"?></literal>.
+ If neither option is specified, the presence of the declaration in
+ the output depends on whether the input <replaceable>value</replaceable>
+ originally contained one.
+
+ The <literal>INCLUDING XMLDECLARATION</literal> option is allowed in both
+ <literal>DOCUMENT</literal> and <literal>CONTENT</literal> modes. In
+ <literal>CONTENT</literal> mode, no structural validation is performed,
+ and the declaration is emitted according to the specified options,
+ even if it would not normally be considered valid by the XML specification.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4537,6 +4571,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index ebe85337c2..999845fdeb 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 8a72b5e70a..0fa2fae281 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4621,7 +4621,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 0b5652071d..868aa6ca38 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -620,6 +620,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -788,8 +790,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16109,14 +16111,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16341,6 +16345,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18037,6 +18056,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18695,6 +18715,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 1f8e2d5467..efb4828a5f 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2497,6 +2497,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3d6e6bdbfd..080d772f6e 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10208,6 +10208,15 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfo(buf, " AS %s",
format_type_with_typemod(xexpr->type,
xexpr->typmod));
+
+ if (xexpr->version)
+ appendStringInfo(buf, " VERSION '%s'", xexpr->version);
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
+
if (xexpr->indent)
appendStringInfoString(buf, " INDENT");
else
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index a4150bff2e..bbb56766d3 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -153,7 +153,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -326,7 +327,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -598,7 +599,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -653,7 +655,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -664,9 +667,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
volatile xmlSaveCtxtPtr ctxt = NULL;
ErrorSaveContext escontext = {T_ErrorSaveContext};
PgXmlErrorContext *xmlerrcxt;
+ StringInfoData xmldecl;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -697,8 +703,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -722,17 +732,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ * Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -755,7 +763,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
*/
xmlNodePtr root;
xmlNodePtr oldroot;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -779,19 +787,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -805,7 +818,49 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION (X078, SQL/XML:2023).
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ initStringInfo(&xmldecl);
+
+ /*
+ * No need to check the return value of print_xml_decl
+ * because we are forcing the XML declaration to be included
+ * by setting 'force_xmldeclaration' to true.
+ * Therefore, print_xml_decl will always succeed and produce output.
+ */
+ print_xml_decl(
+ &xmldecl,
+ /*
+ * Use version from VERSION option (X076, SQL/XML:2023)
+ * if specified; otherwise use the document's version.
+ */
+ xmlserialize_version != NULL ? (const xmlChar *)xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char *)doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used,
+ * otherwise XML declaration and root element will be
+ * serialized in the same line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ if (xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len) < 0 ||
+ xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
+ "could not add XML declaration");
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -840,6 +895,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
xmlBufferFree(buf);
if (doc)
xmlFreeDoc(doc);
+ if (xmldecl.data)
+ pfree(xmldecl.data);
pg_xml_done(xmlerrcxt, true);
@@ -852,6 +909,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1091,7 +1160,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1596,14 +1665,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1612,7 +1687,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index dd00ab420b..6deb2b3988 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -862,6 +862,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 7d3b4198f2..b8d76d8755 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1598,6 +1598,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1620,6 +1627,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index a4af3f717a..cf2cf74838 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -507,6 +507,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f..a79bda7d38 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 103a22a3b1..4557277e8a 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,23 +1226,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 73c411118a..236a07a1ba 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +868,51 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index a85d95358d..30ec649f33 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,23 +1211,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 0ea4f50883..e12683353e 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +293,15 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.34.1
rebase
--
Jim
Attachments:
v5-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v5-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From e54ebfb7b1c02d673449eee321f19daa792136cb Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Wed, 9 Jul 2025 09:02:57 +0200
Subject: [PATCH v5] Add XMLSerialize: version and explicit XML declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Explicit XML declaration (SQL/XML:2023, X078)
This patch adds the options INCLUDING XMLDECLARATION and
EXCLUDING XMLDECLARATION to XMLSERIALIZE, allowing users
to explicitly control the presence of the XML declaration
(e.g., <?xml version="1.0" encoding="UTF-8"?>) in the
serialized output of XML values. If neither option is
specified, the output includes the declaration only if the
input XML value already contained one.
* Version support (SQL/XML:2023, X076)
The VERSION option allows specifying the version string
to use in the XML declaration. If specified, the version
must conform to the lexical rules of the XML standard,
e.g., '1.0' or '1.1'. If omitted or NULL, version '1.0'
is assumed.
In DOCUMENT mode, the version string is validated by
libxml2’s `xmlNewDoc()`, which will raise an error for
invalid versions and a warning for unsupported ones.
No validation is performed in CONTENT mode. This option
has no effect unless INCLUDING XMLDECLARATION is also
specified or the input XML value already contains a
declaration.
Examples:
SELECT xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 69 +++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/ruleutils.c | 9 +
src/backend/utils/adt/xml.c | 133 ++++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 454 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 320 ++++++++++++++++++
src/test/regress/expected/xml_2.out | 427 +++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 81 +++++
15 files changed, 1490 insertions(+), 59 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 0994e08931..b8d65db264 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4520,7 +4520,10 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable>
+ [ VERSION <replaceable>xmlversion</replaceable> ]
+ [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ]
+ [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4530,6 +4533,40 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The <literal>VERSION</literal> option sets the version string
+ used in the XML declaration. If specified, the value of
+ <replaceable>xmlversion</replaceable> must conform to the lexical
+ rules of the XML standard: it must be a string of the form
+ <literal>'1.'</literal> followed by one or more digits (e.g.,
+ <literal>'1.0'</literal>, <literal>'1.1'</literal>). Versions other
+ than 1.x (e.g., <literal>'2.0'</literal>) are not valid in
+ <literal>DOCUMENT</literal> mode and will result in an error. This format
+ is defined in section 2.8,
+ <ulink url="https://www.w3.org/TR/xml/#sec-prolog-dtd">"Prolog and Document Type Declaration"</ulink>,
+ of the XML standard. If the <literal>VERSION</literal> option is omitted or specified as
+ <literal>NULL</literal>, version <literal>1.0</literal> is used by default.
+
+ In <literal>CONTENT</literal> mode, no validation is performed on the version,
+ and it is emitted as specified if an XML declaration is requested.
+ </para>
+
+ <para>
+ The <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> options control
+ whether the serialized output includes an XML declaration such as
+ <literal><?xml version="1.0" encoding="UTF-8"?></literal>.
+ If neither option is specified, the presence of the declaration in
+ the output depends on whether the input <replaceable>value</replaceable>
+ originally contained one.
+
+ The <literal>INCLUDING XMLDECLARATION</literal> option is allowed in both
+ <literal>DOCUMENT</literal> and <literal>CONTENT</literal> modes. In
+ <literal>CONTENT</literal> mode, no structural validation is performed,
+ and the declaration is emitted according to the specified options,
+ even if it would not normally be considered valid by the XML specification.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4537,6 +4574,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index ebe85337c2..999845fdeb 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 8a72b5e70a..0fa2fae281 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4621,7 +4621,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 70a0d832a1..30aabac2fe 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -619,6 +619,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -787,8 +789,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16145,14 +16147,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16377,6 +16381,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18062,6 +18081,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18720,6 +18740,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index d66276801c..6a212d1a6a 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2501,6 +2501,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3d6e6bdbfd..080d772f6e 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10208,6 +10208,15 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfo(buf, " AS %s",
format_type_with_typemod(xexpr->type,
xexpr->typmod));
+
+ if (xexpr->version)
+ appendStringInfo(buf, " VERSION '%s'", xexpr->version);
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
+
if (xexpr->indent)
appendStringInfoString(buf, " INDENT");
else
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index f7b731825f..fcc1b564f1 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -153,7 +153,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -326,7 +327,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -620,7 +621,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -675,7 +677,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -686,9 +689,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
volatile xmlSaveCtxtPtr ctxt = NULL;
ErrorSaveContext escontext = {T_ErrorSaveContext};
PgXmlErrorContext *volatile xmlerrcxt = NULL;
+ StringInfoData xmldecl;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -719,8 +725,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -749,17 +759,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ * Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -782,7 +790,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
*/
xmlNodePtr root;
xmlNodePtr oldroot;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -809,19 +817,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -835,7 +848,49 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION (X078, SQL/XML:2023).
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ initStringInfo(&xmldecl);
+
+ /*
+ * No need to check the return value of print_xml_decl
+ * because we are forcing the XML declaration to be included
+ * by setting 'force_xmldeclaration' to true.
+ * Therefore, print_xml_decl will always succeed and produce output.
+ */
+ print_xml_decl(
+ &xmldecl,
+ /*
+ * Use version from VERSION option (X076, SQL/XML:2023)
+ * if specified; otherwise use the document's version.
+ */
+ xmlserialize_version != NULL ? (const xmlChar *)xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char *)doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used,
+ * otherwise XML declaration and root element will be
+ * serialized in the same line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ if (xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len) < 0 ||
+ xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
+ "could not add XML declaration");
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -870,6 +925,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
xmlBufferFree(buf);
xmlFreeDoc(doc);
+ if (xmldecl.data)
+ pfree(xmldecl.data);
if (xmlerrcxt)
pg_xml_done(xmlerrcxt, true);
@@ -882,6 +939,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1135,7 +1204,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1640,14 +1709,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1656,7 +1731,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 28e2e8dc0f..7166c82063 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -872,6 +872,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 6dfca3cb35..a3cb6774d3 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1604,6 +1604,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1626,6 +1633,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index a4af3f717a..cf2cf74838 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -507,6 +507,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f..a79bda7d38 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 103a22a3b1..4557277e8a 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,23 +1226,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 73c411118a..236a07a1ba 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +868,51 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index a85d95358d..30ec649f33 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,23 +1211,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 0ea4f50883..e12683353e 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +293,15 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.43.0
rebased
--
Jim
Attachments:
v6-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v6-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From 469aaf45d6597bd2bfaa2d042596382f7a9fcc39 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Sun, 27 Jul 2025 19:41:47 +0200
Subject: [PATCH v6] Add XMLSerialize: version and explicit XML declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Explicit XML declaration (SQL/XML:2023, X078)
This patch adds the options INCLUDING XMLDECLARATION and
EXCLUDING XMLDECLARATION to XMLSERIALIZE, allowing users
to explicitly control the presence of the XML declaration
(e.g., <?xml version="1.0" encoding="UTF-8"?>) in the
serialized output of XML values. If neither option is
specified, the output includes the declaration only if the
input XML value already contained one.
* Version support (SQL/XML:2023, X076)
The VERSION option allows specifying the version string
to use in the XML declaration. If specified, the version
must conform to the lexical rules of the XML standard,
e.g., '1.0' or '1.1'. If omitted or NULL, version '1.0'
is assumed.
In DOCUMENT mode, the version string is validated by
libxml2’s `xmlNewDoc()`, which will raise an error for
invalid versions and a warning for unsupported ones.
No validation is performed in CONTENT mode. This option
has no effect unless INCLUDING XMLDECLARATION is also
specified or the input XML value already contains a
declaration.
Examples:
SELECT xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 69 +++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/ruleutils.c | 9 +
src/backend/utils/adt/xml.c | 133 ++++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 454 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 320 ++++++++++++++++++
src/test/regress/expected/xml_2.out | 427 +++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 81 +++++
15 files changed, 1490 insertions(+), 59 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 0994e08931..b8d65db264 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4520,7 +4520,10 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable>
+ [ VERSION <replaceable>xmlversion</replaceable> ]
+ [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ]
+ [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4530,6 +4533,40 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The <literal>VERSION</literal> option sets the version string
+ used in the XML declaration. If specified, the value of
+ <replaceable>xmlversion</replaceable> must conform to the lexical
+ rules of the XML standard: it must be a string of the form
+ <literal>'1.'</literal> followed by one or more digits (e.g.,
+ <literal>'1.0'</literal>, <literal>'1.1'</literal>). Versions other
+ than 1.x (e.g., <literal>'2.0'</literal>) are not valid in
+ <literal>DOCUMENT</literal> mode and will result in an error. This format
+ is defined in section 2.8,
+ <ulink url="https://www.w3.org/TR/xml/#sec-prolog-dtd">"Prolog and Document Type Declaration"</ulink>,
+ of the XML standard. If the <literal>VERSION</literal> option is omitted or specified as
+ <literal>NULL</literal>, version <literal>1.0</literal> is used by default.
+
+ In <literal>CONTENT</literal> mode, no validation is performed on the version,
+ and it is emitted as specified if an XML declaration is requested.
+ </para>
+
+ <para>
+ The <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> options control
+ whether the serialized output includes an XML declaration such as
+ <literal><?xml version="1.0" encoding="UTF-8"?></literal>.
+ If neither option is specified, the presence of the declaration in
+ the output depends on whether the input <replaceable>value</replaceable>
+ originally contained one.
+
+ The <literal>INCLUDING XMLDECLARATION</literal> option is allowed in both
+ <literal>DOCUMENT</literal> and <literal>CONTENT</literal> modes. In
+ <literal>CONTENT</literal> mode, no structural validation is performed,
+ and the declaration is emitted according to the specified options,
+ even if it would not normally be considered valid by the XML specification.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4537,6 +4574,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index ebe85337c2..999845fdeb 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 1a37737d4a..b4d88ee9c4 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4621,7 +4621,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index db43034b9d..ae771aac86 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -619,6 +619,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -787,8 +789,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16140,14 +16142,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16372,6 +16376,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18057,6 +18076,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18715,6 +18735,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index d66276801c..6a212d1a6a 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2501,6 +2501,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3d6e6bdbfd..080d772f6e 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10208,6 +10208,15 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfo(buf, " AS %s",
format_type_with_typemod(xexpr->type,
xexpr->typmod));
+
+ if (xexpr->version)
+ appendStringInfo(buf, " VERSION '%s'", xexpr->version);
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
+
if (xexpr->indent)
appendStringInfoString(buf, " INDENT");
else
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index f7b731825f..fcc1b564f1 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -153,7 +153,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -326,7 +327,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -620,7 +621,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -675,7 +677,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -686,9 +689,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
volatile xmlSaveCtxtPtr ctxt = NULL;
ErrorSaveContext escontext = {T_ErrorSaveContext};
PgXmlErrorContext *volatile xmlerrcxt = NULL;
+ StringInfoData xmldecl;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -719,8 +725,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -749,17 +759,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ * Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -782,7 +790,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
*/
xmlNodePtr root;
xmlNodePtr oldroot;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -809,19 +817,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -835,7 +848,49 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION (X078, SQL/XML:2023).
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ initStringInfo(&xmldecl);
+
+ /*
+ * No need to check the return value of print_xml_decl
+ * because we are forcing the XML declaration to be included
+ * by setting 'force_xmldeclaration' to true.
+ * Therefore, print_xml_decl will always succeed and produce output.
+ */
+ print_xml_decl(
+ &xmldecl,
+ /*
+ * Use version from VERSION option (X076, SQL/XML:2023)
+ * if specified; otherwise use the document's version.
+ */
+ xmlserialize_version != NULL ? (const xmlChar *)xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char *)doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used,
+ * otherwise XML declaration and root element will be
+ * serialized in the same line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ if (xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len) < 0 ||
+ xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
+ "could not add XML declaration");
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -870,6 +925,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
xmlBufferFree(buf);
xmlFreeDoc(doc);
+ if (xmldecl.data)
+ pfree(xmldecl.data);
if (xmlerrcxt)
pg_xml_done(xmlerrcxt, true);
@@ -882,6 +939,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1135,7 +1204,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1640,14 +1709,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1656,7 +1731,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 86a236bd58..adb309572a 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -872,6 +872,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 6dfca3cb35..a3cb6774d3 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1604,6 +1604,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1626,6 +1633,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index a4af3f717a..cf2cf74838 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -507,6 +507,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f..a79bda7d38 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 103a22a3b1..4557277e8a 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,23 +1226,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 73c411118a..236a07a1ba 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +868,51 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index a85d95358d..30ec649f33 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,23 +1211,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 0ea4f50883..e12683353e 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +293,15 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.43.0
rebased
Jim
Attachments:
v7-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchtext/x-patch; charset=UTF-8; name=v7-0001-Add-XMLSerialize-version-and-explicit-XML-declara.patchDownload
From 2e1d0f4cceb6dbbebe9e5eb935e37ff8bdbbf777 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Fri, 7 Nov 2025 10:13:29 +0100
Subject: [PATCH v7] Add XMLSerialize: version and explicit XML declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Explicit XML declaration (SQL/XML:2023, X078)
This patch adds the options INCLUDING XMLDECLARATION and
EXCLUDING XMLDECLARATION to XMLSERIALIZE, allowing users
to explicitly control the presence of the XML declaration
(e.g., <?xml version="1.0" encoding="UTF-8"?>) in the
serialized output of XML values. If neither option is
specified, the output includes the declaration only if the
input XML value already contained one.
* Version support (SQL/XML:2023, X076)
The VERSION option allows specifying the version string
to use in the XML declaration. If specified, the version
must conform to the lexical rules of the XML standard,
e.g., '1.0' or '1.1'. If omitted or NULL, version '1.0'
is assumed.
In DOCUMENT mode, the version string is validated by
libxml2’s `xmlNewDoc()`, which will raise an error for
invalid versions and a warning for unsupported ones.
No validation is performed in CONTENT mode. This option
has no effect unless INCLUDING XMLDECLARATION is also
specified or the input XML value already contains a
declaration.
Examples:
SELECT xmlserialize(
DOCUMENT xmlval AS text
VERSION '1.0'
INCLUDING XMLDECLARATION);
SELECT xmlserialize(
DOCUMENT xmlval AS text
EXCLUDING XMLDECLARATION);
This patch also includes regression tests and documentation.
---
doc/src/sgml/datatype.sgml | 69 +++-
src/backend/catalog/sql_features.txt | 4 +-
src/backend/executor/execExprInterp.c | 4 +-
src/backend/parser/gram.y | 29 +-
src/backend/parser/parse_expr.c | 2 +
src/backend/utils/adt/ruleutils.c | 9 +
src/backend/utils/adt/xml.c | 133 ++++++--
src/include/nodes/parsenodes.h | 2 +
src/include/nodes/primnodes.h | 11 +
src/include/parser/kwlist.h | 1 +
src/include/utils/xml.h | 3 +-
src/test/regress/expected/xml.out | 454 +++++++++++++++++++++++++-
src/test/regress/expected/xml_1.out | 320 ++++++++++++++++++
src/test/regress/expected/xml_2.out | 427 +++++++++++++++++++++++-
src/test/regress/sql/xml.sql | 81 +++++
15 files changed, 1490 insertions(+), 59 deletions(-)
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 1f2829e56a..62d65f4d95 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4518,7 +4518,10 @@ xml '<foo>bar</foo>'
<type>xml</type>, uses the function
<function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
<synopsis>
-XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> [ [ NO ] INDENT ] )
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable>
+ [ VERSION <replaceable>xmlversion</replaceable> ]
+ [ INCLUDING XMLDECLARATION | EXCLUDING XMLDECLARATION ]
+ [ [ NO ] INDENT ] )
</synopsis>
<replaceable>type</replaceable> can be
<type>character</type>, <type>character varying</type>, or
@@ -4528,6 +4531,40 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
you to simply cast the value.
</para>
+ <para>
+ The <literal>VERSION</literal> option sets the version string
+ used in the XML declaration. If specified, the value of
+ <replaceable>xmlversion</replaceable> must conform to the lexical
+ rules of the XML standard: it must be a string of the form
+ <literal>'1.'</literal> followed by one or more digits (e.g.,
+ <literal>'1.0'</literal>, <literal>'1.1'</literal>). Versions other
+ than 1.x (e.g., <literal>'2.0'</literal>) are not valid in
+ <literal>DOCUMENT</literal> mode and will result in an error. This format
+ is defined in section 2.8,
+ <ulink url="https://www.w3.org/TR/xml/#sec-prolog-dtd">"Prolog and Document Type Declaration"</ulink>,
+ of the XML standard. If the <literal>VERSION</literal> option is omitted or specified as
+ <literal>NULL</literal>, version <literal>1.0</literal> is used by default.
+
+ In <literal>CONTENT</literal> mode, no validation is performed on the version,
+ and it is emitted as specified if an XML declaration is requested.
+ </para>
+
+ <para>
+ The <literal>INCLUDING XMLDECLARATION</literal> and
+ <literal>EXCLUDING XMLDECLARATION</literal> options control
+ whether the serialized output includes an XML declaration such as
+ <literal><?xml version="1.0" encoding="UTF-8"?></literal>.
+ If neither option is specified, the presence of the declaration in
+ the output depends on whether the input <replaceable>value</replaceable>
+ originally contained one.
+
+ The <literal>INCLUDING XMLDECLARATION</literal> option is allowed in both
+ <literal>DOCUMENT</literal> and <literal>CONTENT</literal> modes. In
+ <literal>CONTENT</literal> mode, no structural validation is performed,
+ and the declaration is emitted according to the specified options,
+ even if it would not normally be considered valid by the XML specification.
+ </para>
+
<para>
The <literal>INDENT</literal> option causes the result to be
pretty-printed, while <literal>NO INDENT</literal> (which is the
@@ -4535,6 +4572,36 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
type likewise produces the original string.
</para>
+ <para>
+Examples:
+ </para>
+<screen><![CDATA[
+SELECT
+ xmlserialize(
+ DOCUMENT xmlelement(name foo, xmlelement(name bar,42)) AS text
+ VERSION '1.0'
+ INCLUDING XMLDECLARATION
+ INDENT);
+
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT
+ xmlserialize(
+ DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>' AS text
+ EXCLUDING XMLDECLARATION);
+
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+]]></screen>
+
<para>
When a character string value is cast to or from type
<type>xml</type> without going through <type>XMLPARSE</type> or
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index 3a8ad20160..d7454df3ad 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -665,9 +665,9 @@ X072 XMLSerialize: character string serialization YES
X073 XMLSerialize: binary string serialization and CONTENT option NO
X074 XMLSerialize: binary string serialization and DOCUMENT option NO
X075 XMLSerialize: binary string serialization NO
-X076 XMLSerialize: VERSION NO
+X076 XMLSerialize: VERSION YES
X077 XMLSerialize: explicit ENCODING option NO
-X078 XMLSerialize: explicit XML declaration NO
+X078 XMLSerialize: explicit XML declaration YES
X080 Namespaces in XML publishing NO
X081 Query-level XML namespace declarations NO
X082 XML namespace declarations in DML NO
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 0e1a74976f..598c1b7ac3 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4621,7 +4621,9 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue =
PointerGetDatum(xmltotext_with_options(DatumGetXmlP(value),
xexpr->xmloption,
- xexpr->indent));
+ xexpr->indent,
+ xexpr->xmldeclaration,
+ xexpr->version));
*op->resnull = false;
}
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 57fe018654..0bc834948d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -627,6 +627,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <defelt> xmltable_column_option_el
%type <list> xml_namespace_list
%type <target> xml_namespace_el
+%type <ival> opt_xml_declaration_option
+%type <str> opt_xml_declaration_version xmlserialize_version
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
@@ -794,8 +796,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
WAIT WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
- XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
- XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
+ XML_P XMLATTRIBUTES XMLCONCAT XMLDECLARATION XMLELEMENT XMLEXISTS XMLFOREST
+ XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
@@ -16221,14 +16223,16 @@ func_expr_common_subexpr:
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
list_make3($3, $5, $6), @1);
}
- | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
+ | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename opt_xml_declaration_version opt_xml_declaration_option xml_indent_option ')'
{
XmlSerialize *n = makeNode(XmlSerialize);
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
- n->indent = $7;
+ n->version = $7;
+ n->xmldeclaration = $8;
+ n->indent = $9;
n->location = @1;
$$ = (Node *) n;
}
@@ -16453,6 +16457,21 @@ xml_indent_option: INDENT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+xmlserialize_version:
+ VERSION_P Sconst { $$ = $2; }
+ | VERSION_P NULL_P { $$ = NULL; }
+ ;
+
+opt_xml_declaration_version:
+ xmlserialize_version { $$ = $1; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+opt_xml_declaration_option: INCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_INCLUDING_XMLDECLARATION; }
+ | EXCLUDING XMLDECLARATION { $$ = XMLSERIALIZE_EXCLUDING_XMLDECLARATION; }
+ | /*EMPTY*/ { $$ = XMLSERIALIZE_NO_XMLDECLARATION_OPTION; }
+ ;
+
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
| STRIP_P WHITESPACE_P { $$ = false; }
| /*EMPTY*/ { $$ = false; }
@@ -18169,6 +18188,7 @@ unreserved_keyword:
| WRAPPER
| WRITE
| XML_P
+ | XMLDECLARATION
| YEAR_P
| YES_P
| ZONE
@@ -18829,6 +18849,7 @@ bare_label_keyword:
| XML_P
| XMLATTRIBUTES
| XMLCONCAT
+ | XMLDECLARATION
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 32d6ae918c..647e12c4b3 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2502,6 +2502,8 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
xexpr->xmloption = xs->xmloption;
xexpr->indent = xs->indent;
+ xexpr->version = xs->version;
+ xexpr->xmldeclaration = xs->xmldeclaration;
xexpr->location = xs->location;
/* We actually only need these to be able to parse back the expression. */
xexpr->type = targetType;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 556ab057e5..6a42da17b7 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10236,6 +10236,15 @@ get_rule_expr(Node *node, deparse_context *context,
appendStringInfo(buf, " AS %s",
format_type_with_typemod(xexpr->type,
xexpr->typmod));
+
+ if (xexpr->version)
+ appendStringInfo(buf, " VERSION '%s'", xexpr->version);
+
+ if (xexpr->xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " INCLUDING XMLDECLARATION");
+ else if (xexpr->xmldeclaration == XMLSERIALIZE_EXCLUDING_XMLDECLARATION)
+ appendStringInfoString(buf, " EXCLUDING XMLDECLARATION");
+
if (xexpr->indent)
appendStringInfoString(buf, " INDENT");
else
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 41e775570e..e5d13cf002 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -152,7 +152,8 @@ static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone);
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration);
static bool xml_doctype_in_content(const xmlChar *str);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding,
@@ -325,7 +326,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
initStringInfo(&buf);
- if (!print_xml_decl(&buf, version, target_encoding, standalone))
+ if (!print_xml_decl(&buf, version, target_encoding, standalone, false))
{
/*
* If we are not going to produce an XML declaration, eat a single
@@ -619,7 +620,8 @@ xmlconcat(List *args)
print_xml_decl(&buf2,
(!global_version_no_value) ? global_version : NULL,
0,
- global_standalone);
+ global_standalone,
+ NULL);
appendBinaryStringInfo(&buf2, buf.data, buf.len);
buf = buf2;
@@ -674,7 +676,8 @@ xmltotext(PG_FUNCTION_ARGS)
text *
-xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
+xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent,
+ XmlSerializeDeclarationOption xmldeclaration, const char *xmlserialize_version)
{
#ifdef USE_LIBXML
text *volatile result;
@@ -685,9 +688,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
volatile xmlSaveCtxtPtr ctxt = NULL;
ErrorSaveContext escontext = {T_ErrorSaveContext};
PgXmlErrorContext *volatile xmlerrcxt = NULL;
+ StringInfoData xmldecl;
#endif
- if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
+ if (xmloption_arg != XMLOPTION_DOCUMENT &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION &&
+ !indent && !xmlserialize_version)
{
/*
* We don't actually need to do anything, so just return the
@@ -718,8 +724,12 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
errmsg("not an XML document")));
}
- /* If we weren't asked to indent, we're done. */
- if (!indent)
+ /*
+ * If we weren't asked to indent or to explicitly hide / show the
+ * XML declaration, we're done.
+ */
+ if (!indent && !xmlserialize_version &&
+ xmldeclaration == XMLSERIALIZE_NO_XMLDECLARATION_OPTION)
{
xmlFreeDoc(doc);
return (text *) data;
@@ -748,17 +758,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
/*
- * Emit declaration only if the input had one. Note: some versions of
- * xmlSaveToBuffer leak memory if a non-null encoding argument is
- * passed, so don't do that. We don't want any encoding conversion
- * anyway.
+ * Indent the buffer content if the flag INDENT was used.
+ * Note: some versions of xmlSaveToBuffer leak memory if a
+ * non-null encoding argument is passed, so don't do that.
+ * We don't want any encoding conversion anyway. The flag
+ * XML_SAVE_NO_DECL is used here by default, as we manually
+ * add the XML declaration later on with xmlBufferAddHead(),
+ * if applicable.
*/
- if (decl_len == 0)
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
- else
- ctxt = xmlSaveToBuffer(buf, NULL,
- XML_SAVE_FORMAT);
+ ctxt = xmlSaveToBuffer(buf, NULL, XML_SAVE_NO_DECL | (indent ? XML_SAVE_FORMAT : 0));
if (ctxt == NULL || xmlerrcxt->err_occurred)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
@@ -781,7 +789,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
*/
xmlNodePtr root;
xmlNodePtr oldroot;
- xmlNodePtr newline;
+ xmlNodePtr newline = NULL;
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
if (root == NULL || xmlerrcxt->err_occurred)
@@ -808,19 +816,24 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
* freeing of this node manually, and pass NULL here to make sure
* there's not a dangling link.
*/
- newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
- if (newline == NULL || xmlerrcxt->err_occurred)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not allocate xml node");
+ if (indent)
+ {
+ newline = xmlNewDocText(NULL, (const xmlChar *)"\n");
+
+ if (newline == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xml node");
+ }
for (xmlNodePtr node = root->children; node; node = node->next)
{
/* insert newlines between nodes */
- if (node->type != XML_TEXT_NODE && node->prev != NULL)
+ if (node->type != XML_TEXT_NODE && node->prev != NULL && newline != NULL)
{
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
{
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
"could not save newline to xmlBuffer");
}
@@ -834,7 +847,49 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
}
}
- xmlFreeNode(newline);
+ if(newline != NULL)
+ xmlFreeNode(newline);
+ }
+
+ /*
+ * Emit declaration if the input had one or if it was explicitly
+ * requested via INCLUDING XMLDECLARATION (X078, SQL/XML:2023).
+ */
+ if (xmldeclaration == XMLSERIALIZE_INCLUDING_XMLDECLARATION ||
+ (decl_len != 0 && xmldeclaration != XMLSERIALIZE_EXCLUDING_XMLDECLARATION))
+ {
+ initStringInfo(&xmldecl);
+
+ /*
+ * No need to check the return value of print_xml_decl
+ * because we are forcing the XML declaration to be included
+ * by setting 'force_xmldeclaration' to true.
+ * Therefore, print_xml_decl will always succeed and produce output.
+ */
+ print_xml_decl(
+ &xmldecl,
+ /*
+ * Use version from VERSION option (X076, SQL/XML:2023)
+ * if specified; otherwise use the document's version.
+ */
+ xmlserialize_version != NULL ? (const xmlChar *)xmlserialize_version : doc->version,
+ pg_char_to_encoding((const char *)doc->encoding),
+ doc->standalone,
+ true);
+ /*
+ * We add a trailing newline if the flag INDENT was used,
+ * otherwise XML declaration and root element will be
+ * serialized in the same line.
+ */
+ if (indent)
+ appendStringInfoString(&xmldecl, "\n");
+
+ if (xmlBufferAddHead(buf, (const xmlChar *)xmldecl.data, xmldecl.len) < 0 ||
+ xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
+ "could not add XML declaration");
+
+ pfree(xmldecl.data);
}
if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
@@ -869,6 +924,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
xmlBufferFree(buf);
xmlFreeDoc(doc);
+ if (xmldecl.data)
+ pfree(xmldecl.data);
if (xmlerrcxt)
pg_xml_done(xmlerrcxt, true);
@@ -881,6 +938,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
pg_xml_done(xmlerrcxt, false);
+ /*
+ * If the flag VERSION was used with a DOCUMENT xml value we
+ * make sure that the passed version is valid. We let xml_parse()
+ * and xmlNewDoc() decide if an unexpected version deserves an
+ * error or just a warning. CONTENT xml values won't be validated.
+ */
+ if (xmloption_arg == XMLOPTION_DOCUMENT && xmlserialize_version &&
+ !xml_is_document((xmltype *) result))
+ ereport(ERROR,
+ (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
+ errmsg("invalid XML declaration: VERSION '%s'", xmlserialize_version)));
+
return result;
#else
NO_XML_SUPPORT();
@@ -1134,7 +1203,7 @@ xmlroot(xmltype *data, text *version, int standalone)
}
initStringInfo(&buf);
- print_xml_decl(&buf, orig_version, 0, orig_standalone);
+ print_xml_decl(&buf, orig_version, 0, orig_standalone, false);
appendStringInfoString(&buf, str + len);
return stringinfo_to_xmltype(&buf);
@@ -1639,14 +1708,20 @@ finished:
* declaration, we must specify a version (XML requires this).
* Otherwise we only make a declaration if the version is not "1.0",
* which is the default version specified in SQL:2003.
+ *
+ * The parameter 'force_xmldeclaration' forces the function to print
+ * the XML declaration, indenpendently of version and encoding values.
+ * This is useful for XMLSerialize calls with the flag INCLUDING
+ * XMLDECLARATION.
*/
static bool
print_xml_decl(StringInfo buf, const xmlChar *version,
- pg_enc encoding, int standalone)
+ pg_enc encoding, int standalone,
+ bool force_xmldeclaration)
{
if ((version && strcmp((const char *) version, PG_XML_DEFAULT_VERSION) != 0)
|| (encoding && encoding != PG_UTF8)
- || standalone != -1)
+ || standalone != -1 || force_xmldeclaration)
{
appendStringInfoString(buf, "<?xml");
@@ -1655,7 +1730,7 @@ print_xml_decl(StringInfo buf, const xmlChar *version,
else
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
- if (encoding && encoding != PG_UTF8)
+ if ((encoding && encoding != PG_UTF8) || force_xmldeclaration)
{
/*
* XXX might be useful to convert this to IANA names (ISO-8859-1
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d14294a4ec..48fd558b69 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -874,6 +874,8 @@ typedef struct XmlSerialize
Node *expr;
TypeName *typeName;
bool indent; /* [NO] INDENT */
+ const char *version; /* VERSION 'xmlversion' */
+ XmlSerializeDeclarationOption xmldeclaration; /* INCLUDING or EXCLUDING XMLDECLARATION */
ParseLoc location; /* token location, or -1 if unknown */
} XmlSerialize;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 1b4436f2ff..24b4691d68 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1618,6 +1618,13 @@ typedef enum XmlOptionType
XMLOPTION_CONTENT,
} XmlOptionType;
+typedef enum XmlSerializeDeclarationOption
+{
+ XMLSERIALIZE_INCLUDING_XMLDECLARATION, /* Add xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_EXCLUDING_XMLDECLARATION, /* Remove xml declaration in XMLSERIALIZE output */
+ XMLSERIALIZE_NO_XMLDECLARATION_OPTION /* Add xml declaration only if XMLSERIALIZE input has one */
+} XmlSerializeDeclarationOption;
+
typedef struct XmlExpr
{
Expr xpr;
@@ -1640,6 +1647,10 @@ typedef struct XmlExpr
int32 typmod pg_node_attr(query_jumble_ignore);
/* token location, or -1 if unknown */
ParseLoc location;
+ /* xmlserialize flags INCLUDING and EXCLUDING XMLDECLARATION */
+ XmlSerializeDeclarationOption xmldeclaration pg_node_attr(query_jumble_ignore);
+ /* VERSION option fo xmlserialize */
+ const char *version;
} XmlExpr;
/*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 5d4fe27ef9..935d5ce551 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -511,6 +511,7 @@ PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("xmldeclaration", XMLDECLARATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 732dac47bc..ab1ea96071 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -78,7 +78,8 @@ extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *res
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg,
- bool indent);
+ bool indent, XmlSerializeDeclarationOption xmldeclaration,
+ const char *version);
extern char *escape_xml(const char *str);
extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 103a22a3b1..4557277e8a 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -592,23 +592,24 @@ SELECT xmlserialize(CONTENT NULL AS text INDENT);
-- indent with XML declaration
SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
-----------------------------------------
- <?xml version="1.0" encoding="UTF-8"?>+
- <foo> +
- <bar> +
- <val>73</val> +
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar><val>73</val></bar></foo>' AS text INDENT);
- xmlserialize
--------------------
- <foo> +
- <bar> +
- <val>73</val>+
- </bar> +
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar> +
+ <val>73</val> +
+ </bar> +
</foo>
(1 row)
@@ -676,6 +677,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -824,23 +1226,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 73c411118a..236a07a1ba 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -454,6 +454,281 @@ ERROR: unsupported XML feature
LINE 1: SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> ...
^
DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="U...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::x...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: unsupported XML feature at character 30
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
@@ -593,6 +868,51 @@ ERROR: unsupported XML feature
LINE 1: ...TE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar...
^
DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
+ERROR: unsupported XML feature
+LINE 1: ...TE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar...
+ ^
+DETAIL: This functionality requires the server to be built with libxml support.
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index a85d95358d..30ec649f33 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -662,6 +662,407 @@ SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text IN
</foo>
(1 row)
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+ xmlserialize
+-------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+ xmlserialize
+-----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+ xmlserialize
+----------------------------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="no"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+ xmlserialize
+-------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="no"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8" standalone="yes"?>+
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+---------------------------------------
+ <?xml version="1.1" encoding="UTF8"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+--------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8" standalone="yes"?>+
+ txt +
+ <foo> +
+ <bar>42</bar> +
+ </foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+ xmlserialize
+-----------------
+ txt +
+ <foo> +
+ <bar>42</bar>+
+ </foo>
+(1 row)
+
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+--------------------------
+ <foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+ xmlserialize
+-----------------------------
+ txt<foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+ xmlserialize
+------------------------------------------------------------------
+ <?xml version="1.0" encoding="UTF8"?>txt<foo><bar>42</bar></foo>
+(1 row)
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+WARNING: line 1: Unsupported version '1.1'
+<?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+ ^
+ xmlserialize
+---------------------------------------------------------------
+ <?xml version="1.1" encoding="UTF8"?><foo><bar>42</bar></foo>
+(1 row)
+
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION '2.0'
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ''
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION ' '
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+ERROR: invalid XML declaration: VERSION 'foo'
+\set VERBOSITY default
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
?column?
----------
@@ -810,23 +1211,41 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
- table_name | view_definition
-------------+---------------------------------------------------------------------------------------------------------------------------------------
+ table_name | view_definition
+------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview10 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INDENT) AS "xmlserialize";
xmlview11 | SELECT (XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS character varying NO INDENT))::character varying AS "xmlserialize";
+ xmlview12 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview13 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview14 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview15 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview16 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview17 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
+ xmlview18 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT) AS "xmlserialize";
+ xmlview19 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION NO INDENT) AS "xmlserialize";
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
+ xmlview20 | SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' NO INDENT) AS "xmlserialize";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
- xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
+ xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement" +
| FROM emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
xmlview8 | SELECT (XMLSERIALIZE(CONTENT 'good'::xml AS character(10) NO INDENT))::character(10) AS "xmlserialize";
xmlview9 | SELECT XMLSERIALIZE(CONTENT 'good'::xml AS text NO INDENT) AS "xmlserialize";
-(11 rows)
+(20 rows)
-- Text XPath expressions evaluation
SELECT xpath('/value', data) FROM xmltest;
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 0ea4f50883..e12683353e 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -172,6 +172,78 @@ SELECT xmlserialize(CONTENT '<foo><bar><val x="y">42</val></bar></foo>' AS text
SELECT xmlserialize(DOCUMENT '<foo> <bar></bar> </foo>' AS text INDENT);
SELECT xmlserialize(CONTENT 'text node<foo> <bar></bar> </foo>' AS text INDENT);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text EXCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text INCLUDING XMLDECLARATION INDENT);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0');
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1');
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION);
+-- 'version' + 'indent' (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="no"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INDENT);
+-- 'indent' + 'version' (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?><foo><bar>42</bar></foo>'::xml AS text VERSION '1.0' EXCLUDING XMLDECLARATION INDENT);
+-- 'indent' + 'version' + 'including xmldeclaration' and 'excluding xmldeclaration'(CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION INDENT);
+SELECT xmlserialize(CONTENT '<?xml version="1.0" encoding="UTF-8"?>txt<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' EXCLUDING XMLDECLARATION INDENT);
+--'version' with null value (DOCUMENT)
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+--'version' with null value (CONTENT)
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL EXCLUDING XMLDECLARATION);
+SELECT xmlserialize(CONTENT 'txt<foo><bar>42</bar></foo>'::xml AS text VERSION NULL INCLUDING XMLDECLARATION);
+
+-- 'version' + 'including xmldeclaration' warning and error messages
+\set VERBOSITY terse
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '1.1' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '2.0' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION '' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION ' ' INCLUDING XMLDECLARATION);
+SELECT xmlserialize(DOCUMENT '<foo><bar>42</bar></foo>'::xml AS text VERSION 'foo' INCLUDING XMLDECLARATION);
+\set VERBOSITY default
+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
SELECT xml '<abc/>' IS NOT DOCUMENT;
@@ -221,6 +293,15 @@ CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
CREATE VIEW xmlview10 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text indent);
CREATE VIEW xmlview11 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS character varying no indent);
+CREATE VIEW xmlview12 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration);
+CREATE VIEW xmlview13 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration);
+CREATE VIEW xmlview14 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration indent);
+CREATE VIEW xmlview15 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration indent);
+CREATE VIEW xmlview16 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text including xmldeclaration no indent);
+CREATE VIEW xmlview17 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text excluding xmldeclaration no indent);
+CREATE VIEW xmlview18 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration indent);
+CREATE VIEW xmlview19 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0' including xmldeclaration no indent);
+CREATE VIEW xmlview20 AS SELECT xmlserialize(document '<foo><bar>42</bar></foo>' AS text version '1.0');
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
--
2.43.0