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
From adfc1b9137ac8b004fe9e495fb79f2bf4b21cf49 Mon Sep 17 00:00:00 2001 From: Jim Jones <jim.jo...@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