Various fixes in the logic of XML functions:
- Add new SQL command SET XML OPTION (also available via regular GUC) to control the DOCUMENT vs. CONTENT option in implicit parsing and serialization operations. - Subtle corrections in the handling of the standalone property in xmlroot(). - Allow xmlroot() to work on content fragments. - Subtle corrections in the handling of the version property in xmlconcat(). - Code refactoring for producing XML declarations.
This commit is contained in:
parent
9597446d11
commit
22bd156ff0
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.105 2007/01/25 04:35:10 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.106 2007/01/25 11:53:50 petere Exp $ -->
|
||||||
|
|
||||||
<chapter Id="runtime-config">
|
<chapter Id="runtime-config">
|
||||||
<title>Server Configuration</title>
|
<title>Server Configuration</title>
|
||||||
@ -3558,6 +3558,38 @@ SELECT * FROM parent WHERE key = 2400;
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="guc-xmloption" xreflabel="xmloption">
|
||||||
|
<term><varname>xmloption</varname> (<type>string</type>)</term>
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>xmloption</> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>SET XML OPTION</></primary>
|
||||||
|
</indexterm>
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>XML option</></primary>
|
||||||
|
</indexterm>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Sets whether <literal>DOCUMENT</literal> or
|
||||||
|
<literal>CONTENT</literal> is implicit when converting between
|
||||||
|
XML and character string values. See <xref
|
||||||
|
linkend="datatype-xml"> for a description of this. Valid
|
||||||
|
values are <literal>DOCUMENT</literal> and
|
||||||
|
<literal>CONTENT</literal>. The default is
|
||||||
|
<literal>CONTENT</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
According to the SQL standard, the command to set this option is
|
||||||
|
<synopsis>
|
||||||
|
SET XML OPTION { DOCUMENT | CONTENT };
|
||||||
|
</synopsis>
|
||||||
|
This syntax is also available in PostgreSQL.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</sect2>
|
</sect2>
|
||||||
<sect2 id="runtime-config-client-format">
|
<sect2 id="runtime-config-client-format">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.185 2007/01/18 13:59:11 petere Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.186 2007/01/25 11:53:50 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="datatype">
|
<chapter id="datatype">
|
||||||
<title id="datatype-title">Data Types</title>
|
<title id="datatype-title">Data Types</title>
|
||||||
@ -3474,6 +3474,24 @@ XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <repla
|
|||||||
you to simply cast the value.
|
you to simply cast the value.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When character string values are cast to or from type
|
||||||
|
<type>xml</type> without going through <type>XMLPARSE</type> or
|
||||||
|
<type>XMLSERIALIZE</type>, respectively, the choice of
|
||||||
|
<literal>DOCUMENT</literal> versus <literal>CONTENT</literal> is
|
||||||
|
determined by the <quote>XML option</quote> session configuration
|
||||||
|
parameter, which can be set using the standard command
|
||||||
|
<synopsis>
|
||||||
|
SET XML OPTION { DOCUMENT | CONTENT };
|
||||||
|
</synopsis>
|
||||||
|
or the more PostgreSQL-like syntax
|
||||||
|
<synopsis>
|
||||||
|
SET xmloption TO { DOCUMENT | CONTENT };
|
||||||
|
</synopsis>
|
||||||
|
The default is <literal>CONTENT</literal>, so all forms of XML
|
||||||
|
data are allowed.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Care must be taken when dealing with multiple character encodings
|
Care must be taken when dealing with multiple character encodings
|
||||||
on the client, server, and in the XML data passed through them.
|
on the client, server, and in the XML data passed through them.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.208 2007/01/20 09:27:19 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.209 2007/01/25 11:53:50 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2797,10 +2797,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
|||||||
|
|
||||||
e = (ExprState *) lthird(xmlExpr->args);
|
e = (ExprState *) lthird(xmlExpr->args);
|
||||||
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
if (isnull)
|
standalone = DatumGetInt32(value);
|
||||||
standalone = 0;
|
|
||||||
else
|
|
||||||
standalone = (DatumGetBool(value) ? 1 : -1);
|
|
||||||
|
|
||||||
*isNull = false;
|
*isNull = false;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.576 2007/01/23 05:07:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.577 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -60,6 +60,7 @@
|
|||||||
#include "utils/date.h"
|
#include "utils/date.h"
|
||||||
#include "utils/datetime.h"
|
#include "utils/datetime.h"
|
||||||
#include "utils/numeric.h"
|
#include "utils/numeric.h"
|
||||||
|
#include "utils/xml.h"
|
||||||
|
|
||||||
|
|
||||||
/* Location tracking support --- simpler than bison's default */
|
/* Location tracking support --- simpler than bison's default */
|
||||||
@ -439,7 +440,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
|
|
||||||
WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
|
WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
|
||||||
|
|
||||||
XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
|
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
|
||||||
XMLPI XMLROOT XMLSERIALIZE
|
XMLPI XMLROOT XMLSERIALIZE
|
||||||
|
|
||||||
YEAR_P YES_P
|
YEAR_P YES_P
|
||||||
@ -1112,6 +1113,13 @@ set_rest: var_name TO var_list_or_default
|
|||||||
n->args = NIL;
|
n->args = NIL;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
|
| XML_P OPTION document_or_content
|
||||||
|
{
|
||||||
|
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||||
|
n->name = "xmloption";
|
||||||
|
n->args = list_make1(makeStringConst($3 ? "DOCUMENT" : "CONTENT", NULL));
|
||||||
|
$$ = n;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
var_name:
|
var_name:
|
||||||
@ -7938,21 +7946,13 @@ xml_root_version: VERSION_P a_expr
|
|||||||
;
|
;
|
||||||
|
|
||||||
opt_xml_root_standalone: ',' STANDALONE_P YES_P
|
opt_xml_root_standalone: ',' STANDALONE_P YES_P
|
||||||
{ $$ = (Node *) makeBoolAConst(true); }
|
{ $$ = (Node *) makeIntConst(XML_STANDALONE_YES); }
|
||||||
| ',' STANDALONE_P NO
|
| ',' STANDALONE_P NO
|
||||||
{ $$ = (Node *) makeBoolAConst(false); }
|
{ $$ = (Node *) makeIntConst(XML_STANDALONE_NO); }
|
||||||
| ',' STANDALONE_P NO VALUE_P
|
| ',' STANDALONE_P NO VALUE_P
|
||||||
{
|
{ $$ = (Node *) makeIntConst(XML_STANDALONE_NO_VALUE); }
|
||||||
A_Const *val = makeNode(A_Const);
|
|
||||||
val->val.type = T_Null;
|
|
||||||
$$ = (Node *) val;
|
|
||||||
}
|
|
||||||
| /*EMPTY*/
|
| /*EMPTY*/
|
||||||
{
|
{ $$ = (Node *) makeIntConst(XML_STANDALONE_OMITTED); }
|
||||||
A_Const *val = makeNode(A_Const);
|
|
||||||
val->val.type = T_Null;
|
|
||||||
$$ = (Node *) val;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
|
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
|
||||||
@ -8864,6 +8864,7 @@ unreserved_keyword:
|
|||||||
| WITHOUT
|
| WITHOUT
|
||||||
| WORK
|
| WORK
|
||||||
| WRITE
|
| WRITE
|
||||||
|
| XML_P
|
||||||
| YEAR_P
|
| YEAR_P
|
||||||
| YES_P
|
| YES_P
|
||||||
| ZONE
|
| ZONE
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.183 2007/01/23 05:07:18 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.184 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -380,6 +380,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"without", WITHOUT},
|
{"without", WITHOUT},
|
||||||
{"work", WORK},
|
{"work", WORK},
|
||||||
{"write", WRITE},
|
{"write", WRITE},
|
||||||
|
{"xml", XML_P},
|
||||||
{"xmlattributes", XMLATTRIBUTES},
|
{"xmlattributes", XMLATTRIBUTES},
|
||||||
{"xmlconcat", XMLCONCAT},
|
{"xmlconcat", XMLCONCAT},
|
||||||
{"xmlelement", XMLELEMENT},
|
{"xmlelement", XMLELEMENT},
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.208 2007/01/14 13:11:53 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.209 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1481,7 +1481,8 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
|
|||||||
newe = coerce_to_specific_type(pstate, newe, TEXTOID,
|
newe = coerce_to_specific_type(pstate, newe, TEXTOID,
|
||||||
"XMLROOT");
|
"XMLROOT");
|
||||||
else
|
else
|
||||||
newe = coerce_to_boolean(pstate, newe, "XMLROOT");
|
newe = coerce_to_specific_type(pstate, newe, INT4OID,
|
||||||
|
"XMLROOT");
|
||||||
break;
|
break;
|
||||||
case IS_DOCUMENT:
|
case IS_DOCUMENT:
|
||||||
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.21 2007/01/23 23:39:16 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.22 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -67,11 +67,14 @@ static void xml_ereport_by_code(int level, int sqlcode,
|
|||||||
const char *msg, int errcode);
|
const char *msg, int errcode);
|
||||||
static xmlChar *xml_text2xmlChar(text *in);
|
static xmlChar *xml_text2xmlChar(text *in);
|
||||||
static int parse_xml_decl(const xmlChar *str, size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone);
|
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);
|
||||||
static xmlDocPtr xml_parse(text *data, bool is_document, bool preserve_whitespace, xmlChar *encoding);
|
static xmlDocPtr xml_parse(text *data, bool is_document, bool preserve_whitespace, xmlChar *encoding);
|
||||||
|
|
||||||
#endif /* USE_LIBXML */
|
#endif /* USE_LIBXML */
|
||||||
|
|
||||||
XmlBinaryType xmlbinary;
|
XmlBinaryType xmlbinary;
|
||||||
|
XmlOptionType xmloption;
|
||||||
|
|
||||||
|
|
||||||
#define NO_XML_SUPPORT() \
|
#define NO_XML_SUPPORT() \
|
||||||
ereport(ERROR, \
|
ereport(ERROR, \
|
||||||
@ -97,7 +100,7 @@ xml_in(PG_FUNCTION_ARGS)
|
|||||||
* Parse the data to check if it is well-formed XML data. Assume
|
* Parse the data to check if it is well-formed XML data. Assume
|
||||||
* that ERROR occurred if parsing failed.
|
* that ERROR occurred if parsing failed.
|
||||||
*/
|
*/
|
||||||
doc = xml_parse(vardata, false, true, NULL);
|
doc = xml_parse(vardata, (xmloption == XMLOPTION_DOCUMENT), true, NULL);
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
|
|
||||||
PG_RETURN_XML_P(vardata);
|
PG_RETURN_XML_P(vardata);
|
||||||
@ -129,48 +132,13 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
|
|||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
|
|
||||||
#ifdef USE_LIBXML
|
#ifdef USE_LIBXML
|
||||||
/*
|
|
||||||
* On output, we adjust the XML declaration as follows. (These
|
|
||||||
* rules are the moral equivalent of the clause "Serialization of
|
|
||||||
* an XML value" in the SQL standard.)
|
|
||||||
*
|
|
||||||
* We try to avoid generating an XML declaration if possible.
|
|
||||||
* This is so that you don't get trivial things like xml '<foo/>'
|
|
||||||
* resulting in '<?xml version="1.0"?><foo/>', which would surely
|
|
||||||
* be annoying. We must provide a declaration if the standalone
|
|
||||||
* property is specified or if we include an encoding
|
|
||||||
* specification. If we have a 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.
|
|
||||||
*/
|
|
||||||
if ((res_code = parse_xml_decl((xmlChar *) str, &len, &version, &encoding, &standalone)) == 0)
|
if ((res_code = parse_xml_decl((xmlChar *) str, &len, &version, &encoding, &standalone)) == 0)
|
||||||
{
|
{
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
|
|
||||||
initStringInfo(&buf);
|
initStringInfo(&buf);
|
||||||
|
|
||||||
if ((version && strcmp((char *) version, PG_XML_DEFAULT_VERSION) != 0)
|
if (!print_xml_decl(&buf, version, target_encoding, standalone))
|
||||||
|| (target_encoding && target_encoding != PG_UTF8)
|
|
||||||
|| standalone != -1)
|
|
||||||
{
|
|
||||||
appendStringInfoString(&buf, "<?xml");
|
|
||||||
if (version)
|
|
||||||
appendStringInfo(&buf, " version=\"%s\"", version);
|
|
||||||
else
|
|
||||||
appendStringInfo(&buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
|
|
||||||
if (target_encoding && target_encoding != PG_UTF8)
|
|
||||||
/* XXX might be useful to convert this to IANA names
|
|
||||||
* (ISO-8859-1 instead of LATIN1 etc.); needs field
|
|
||||||
* experience */
|
|
||||||
appendStringInfo(&buf, " encoding=\"%s\"", pg_encoding_to_char(target_encoding));
|
|
||||||
if (standalone == 1)
|
|
||||||
appendStringInfoString(&buf, " standalone=\"yes\"");
|
|
||||||
else if (standalone == 0)
|
|
||||||
appendStringInfoString(&buf, " standalone=\"no\"");
|
|
||||||
appendStringInfoString(&buf, "?>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we are not going to produce an XML declaration, eat
|
* If we are not going to produce an XML declaration, eat
|
||||||
@ -231,7 +199,7 @@ xml_recv(PG_FUNCTION_ARGS)
|
|||||||
* Parse the data to check if it is well-formed XML data. Assume
|
* Parse the data to check if it is well-formed XML data. Assume
|
||||||
* that ERROR occurred if parsing failed.
|
* that ERROR occurred if parsing failed.
|
||||||
*/
|
*/
|
||||||
doc = xml_parse(result, false, true, encoding);
|
doc = xml_parse(result, (xmloption == XMLOPTION_DOCUMENT), true, encoding);
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
|
|
||||||
newstr = (char *) pg_do_encoding_conversion((unsigned char *) str,
|
newstr = (char *) pg_do_encoding_conversion((unsigned char *) str,
|
||||||
@ -296,6 +264,7 @@ stringinfo_to_xmltype(StringInfo buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NOT_USED
|
||||||
static xmltype *
|
static xmltype *
|
||||||
cstring_to_xmltype(const char *string)
|
cstring_to_xmltype(const char *string)
|
||||||
{
|
{
|
||||||
@ -309,6 +278,7 @@ cstring_to_xmltype(const char *string)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static xmltype *
|
static xmltype *
|
||||||
@ -394,9 +364,11 @@ xmlconcat(List *args)
|
|||||||
if (standalone < 0)
|
if (standalone < 0)
|
||||||
global_standalone = -1;
|
global_standalone = -1;
|
||||||
|
|
||||||
if (!global_version)
|
if (!version)
|
||||||
|
global_version_no_value = true;
|
||||||
|
else if (!global_version)
|
||||||
global_version = xmlStrdup(version);
|
global_version = xmlStrdup(version);
|
||||||
else if (version && xmlStrcmp(version, global_version) != 0)
|
else if (xmlStrcmp(version, global_version) != 0)
|
||||||
global_version_no_value = true;
|
global_version_no_value = true;
|
||||||
|
|
||||||
appendStringInfoString(&buf, str + len);
|
appendStringInfoString(&buf, str + len);
|
||||||
@ -409,17 +381,10 @@ xmlconcat(List *args)
|
|||||||
|
|
||||||
initStringInfo(&buf2);
|
initStringInfo(&buf2);
|
||||||
|
|
||||||
if (!global_version_no_value && global_version)
|
print_xml_decl(&buf2,
|
||||||
appendStringInfo(&buf2, "<?xml version=\"%s\"", global_version);
|
(!global_version_no_value && global_version) ? global_version : NULL,
|
||||||
else
|
0,
|
||||||
appendStringInfo(&buf2, "<?xml version=\"%s\"", PG_XML_DEFAULT_VERSION);
|
global_standalone);
|
||||||
|
|
||||||
if (global_standalone == 1)
|
|
||||||
appendStringInfoString(&buf2, " standalone=\"yes\"");
|
|
||||||
else if (global_standalone == 0)
|
|
||||||
appendStringInfoString(&buf2, " standalone=\"no\"");
|
|
||||||
|
|
||||||
appendStringInfoString(&buf2, "?>");
|
|
||||||
|
|
||||||
appendStringInfoString(&buf2, buf.data);
|
appendStringInfoString(&buf2, buf.data);
|
||||||
buf = buf2;
|
buf = buf2;
|
||||||
@ -458,7 +423,7 @@ texttoxml(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
text *data = PG_GETARG_TEXT_P(0);
|
text *data = PG_GETARG_TEXT_P(0);
|
||||||
|
|
||||||
PG_RETURN_XML_P(xmlparse(data, false, true));
|
PG_RETURN_XML_P(xmlparse(data, (xmloption == XMLOPTION_DOCUMENT), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -595,44 +560,45 @@ xmltype *
|
|||||||
xmlroot(xmltype *data, text *version, int standalone)
|
xmlroot(xmltype *data, text *version, int standalone)
|
||||||
{
|
{
|
||||||
#ifdef USE_LIBXML
|
#ifdef USE_LIBXML
|
||||||
xmltype *result;
|
char *str;
|
||||||
xmlDocPtr doc;
|
size_t len;
|
||||||
xmlBufferPtr buffer;
|
xmlChar *orig_version;
|
||||||
xmlSaveCtxtPtr save;
|
int orig_standalone;
|
||||||
|
StringInfoData buf;
|
||||||
|
|
||||||
doc = xml_parse((text *) data, true, true, NULL);
|
len = VARSIZE(data) - VARHDRSZ;
|
||||||
|
str = palloc(len + 1);
|
||||||
|
memcpy(str, VARDATA(data), len);
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
|
||||||
|
|
||||||
if (version)
|
if (version)
|
||||||
doc->version = xmlStrdup(xml_text2xmlChar(version));
|
orig_version = xml_text2xmlChar(version);
|
||||||
else
|
else
|
||||||
doc->version = NULL;
|
orig_version = NULL;
|
||||||
|
|
||||||
switch (standalone)
|
switch (standalone)
|
||||||
{
|
{
|
||||||
case 1:
|
case XML_STANDALONE_YES:
|
||||||
doc->standalone = 1;
|
orig_standalone = 1;
|
||||||
break;
|
break;
|
||||||
case -1:
|
case XML_STANDALONE_NO:
|
||||||
doc->standalone = 0;
|
orig_standalone = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
case XML_STANDALONE_NO_VALUE:
|
||||||
doc->standalone = -1;
|
orig_standalone = -1;
|
||||||
|
break;
|
||||||
|
case XML_STANDALONE_OMITTED:
|
||||||
|
/* leave original value */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = xmlBufferCreate();
|
initStringInfo(&buf);
|
||||||
save = xmlSaveToBuffer(buffer, "UTF-8", 0);
|
print_xml_decl(&buf, orig_version, 0, orig_standalone);
|
||||||
xmlSaveDoc(save, doc);
|
appendStringInfoString(&buf, str + len);
|
||||||
xmlSaveClose(save);
|
|
||||||
|
|
||||||
xmlFreeDoc(doc);
|
return stringinfo_to_xmltype(&buf);
|
||||||
|
|
||||||
result = cstring_to_xmltype((char *) pg_do_encoding_conversion((unsigned char *) xmlBufferContent(buffer),
|
|
||||||
xmlBufferLength(buffer),
|
|
||||||
PG_UTF8,
|
|
||||||
GetDatabaseEncoding()));
|
|
||||||
xmlBufferFree(buffer);
|
|
||||||
return result;
|
|
||||||
#else
|
#else
|
||||||
NO_XML_SUPPORT();
|
NO_XML_SUPPORT();
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -971,6 +937,53 @@ finished:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write an XML declaration. On output, we adjust the XML declaration
|
||||||
|
* as follows. (These rules are the moral equivalent of the clause
|
||||||
|
* "Serialization of an XML value" in the SQL standard.)
|
||||||
|
*
|
||||||
|
* We try to avoid generating an XML declaration if possible. This is
|
||||||
|
* so that you don't get trivial things like xml '<foo/>' resulting in
|
||||||
|
* '<?xml version="1.0"?><foo/>', which would surely be annoying. We
|
||||||
|
* must provide a declaration if the standalone property is specified
|
||||||
|
* or if we include an encoding declaration. If we have a
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
print_xml_decl(StringInfo buf, const xmlChar *version, pg_enc encoding, int standalone)
|
||||||
|
{
|
||||||
|
if ((version && strcmp((char *) version, PG_XML_DEFAULT_VERSION) != 0)
|
||||||
|
|| (encoding && encoding != PG_UTF8)
|
||||||
|
|| standalone != -1)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, "<?xml");
|
||||||
|
|
||||||
|
if (version)
|
||||||
|
appendStringInfo(buf, " version=\"%s\"", version);
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, " version=\"%s\"", PG_XML_DEFAULT_VERSION);
|
||||||
|
|
||||||
|
if (encoding && encoding != PG_UTF8)
|
||||||
|
/* XXX might be useful to convert this to IANA names
|
||||||
|
* (ISO-8859-1 instead of LATIN1 etc.); needs field
|
||||||
|
* experience */
|
||||||
|
appendStringInfo(buf, " encoding=\"%s\"", pg_encoding_to_char(encoding));
|
||||||
|
|
||||||
|
if (standalone == 1)
|
||||||
|
appendStringInfoString(buf, " standalone=\"yes\"");
|
||||||
|
else if (standalone == 0)
|
||||||
|
appendStringInfoString(buf, " standalone=\"no\"");
|
||||||
|
appendStringInfoString(buf, "?>");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a C string to XML internal representation
|
* Convert a C string to XML internal representation
|
||||||
*
|
*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.370 2007/01/25 04:35:11 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.371 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------
|
*--------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -145,6 +145,7 @@ static const char *assign_canonical_path(const char *newval, bool doit, GucSourc
|
|||||||
static const char *assign_backslash_quote(const char *newval, bool doit, GucSource source);
|
static const char *assign_backslash_quote(const char *newval, bool doit, GucSource source);
|
||||||
static const char *assign_timezone_abbreviations(const char *newval, bool doit, GucSource source);
|
static const char *assign_timezone_abbreviations(const char *newval, bool doit, GucSource source);
|
||||||
static const char *assign_xmlbinary(const char *newval, bool doit, GucSource source);
|
static const char *assign_xmlbinary(const char *newval, bool doit, GucSource source);
|
||||||
|
static const char *assign_xmloption(const char *newval, bool doit, GucSource source);
|
||||||
|
|
||||||
static bool assign_tcp_keepalives_idle(int newval, bool doit, GucSource source);
|
static bool assign_tcp_keepalives_idle(int newval, bool doit, GucSource source);
|
||||||
static bool assign_tcp_keepalives_interval(int newval, bool doit, GucSource source);
|
static bool assign_tcp_keepalives_interval(int newval, bool doit, GucSource source);
|
||||||
@ -233,6 +234,7 @@ static char *XactIsoLevel_string;
|
|||||||
static char *data_directory;
|
static char *data_directory;
|
||||||
static char *custom_variable_classes;
|
static char *custom_variable_classes;
|
||||||
static char *xmlbinary_string;
|
static char *xmlbinary_string;
|
||||||
|
static char *xmloption_string;
|
||||||
static int max_function_args;
|
static int max_function_args;
|
||||||
static int max_index_keys;
|
static int max_index_keys;
|
||||||
static int max_identifier_length;
|
static int max_identifier_length;
|
||||||
@ -2292,6 +2294,16 @@ static struct config_string ConfigureNamesString[] =
|
|||||||
"base64", assign_xmlbinary, NULL
|
"base64", assign_xmlbinary, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
||||||
|
gettext_noop("Sets whether XML data in implicit parsing and serialization "
|
||||||
|
"operations is to be considered as documents or content fragments."),
|
||||||
|
gettext_noop("Valid values are DOCUMENT and CONTENT.")
|
||||||
|
},
|
||||||
|
&xmloption_string,
|
||||||
|
"content", assign_xmloption, NULL
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"temp_tablespaces", PGC_USERSET, PGC_S_FILE,
|
{"temp_tablespaces", PGC_USERSET, PGC_S_FILE,
|
||||||
gettext_noop("Sets the tablespaces suitable for creating new objects and sort files."),
|
gettext_noop("Sets the tablespaces suitable for creating new objects and sort files."),
|
||||||
@ -6516,6 +6528,24 @@ assign_xmlbinary(const char *newval, bool doit, GucSource source)
|
|||||||
return newval;
|
return newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
assign_xmloption(const char *newval, bool doit, GucSource source)
|
||||||
|
{
|
||||||
|
XmlOptionType xo;
|
||||||
|
|
||||||
|
if (pg_strcasecmp(newval, "document") == 0)
|
||||||
|
xo = XMLOPTION_DOCUMENT;
|
||||||
|
else if (pg_strcasecmp(newval, "content") == 0)
|
||||||
|
xo = XMLOPTION_CONTENT;
|
||||||
|
else
|
||||||
|
return NULL; /* reject */
|
||||||
|
|
||||||
|
if (doit)
|
||||||
|
xmloption = xo;
|
||||||
|
|
||||||
|
return newval;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
assign_tcp_keepalives_idle(int newval, bool doit, GucSource source)
|
assign_tcp_keepalives_idle(int newval, bool doit, GucSource source)
|
||||||
{
|
{
|
||||||
|
@ -406,6 +406,8 @@
|
|||||||
#default_transaction_read_only = off
|
#default_transaction_read_only = off
|
||||||
#statement_timeout = 0 # 0 is disabled
|
#statement_timeout = 0 # 0 is disabled
|
||||||
#vacuum_freeze_min_age = 100000000
|
#vacuum_freeze_min_age = 100000000
|
||||||
|
#xmlbinary = 'base64'
|
||||||
|
#xmloption = 'content'
|
||||||
|
|
||||||
# - Locale and Formatting -
|
# - Locale and Formatting -
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.12 2007/01/20 09:27:20 petere Exp $
|
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.13 2007/01/25 11:53:51 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -34,6 +34,14 @@ extern Datum xmlconcat2(PG_FUNCTION_ARGS);
|
|||||||
extern Datum texttoxml(PG_FUNCTION_ARGS);
|
extern Datum texttoxml(PG_FUNCTION_ARGS);
|
||||||
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XML_STANDALONE_YES,
|
||||||
|
XML_STANDALONE_NO,
|
||||||
|
XML_STANDALONE_NO_VALUE,
|
||||||
|
XML_STANDALONE_OMITTED
|
||||||
|
} XmlStandaloneType;
|
||||||
|
|
||||||
extern xmltype *xmlconcat(List *args);
|
extern xmltype *xmlconcat(List *args);
|
||||||
extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
|
extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
|
||||||
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
|
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
|
||||||
@ -53,4 +61,12 @@ typedef enum
|
|||||||
|
|
||||||
extern XmlBinaryType xmlbinary;
|
extern XmlBinaryType xmlbinary;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XMLOPTION_DOCUMENT,
|
||||||
|
XMLOPTION_CONTENT
|
||||||
|
} XmlOptionType;
|
||||||
|
|
||||||
|
extern XmlOptionType xmloption;
|
||||||
|
|
||||||
#endif /* XML_H */
|
#endif /* XML_H */
|
||||||
|
@ -53,7 +53,7 @@ SELECT xmlconcat('hello', 'you');
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT xmlconcat(1, 2);
|
SELECT xmlconcat(1, 2);
|
||||||
ERROR: argument of XMLCONCAT must be type xml, not type integer
|
ERROR: argument of XMLCONCAT must be type "xml", not type integer
|
||||||
SELECT xmlconcat('bad', '<syntax');
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
ERROR: invalid XML content
|
ERROR: invalid XML content
|
||||||
DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax line 1
|
DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax line 1
|
||||||
@ -61,6 +61,12 @@ DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax li
|
|||||||
^
|
^
|
||||||
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
xmlconcat
|
xmlconcat
|
||||||
|
--------------
|
||||||
|
<foo/><bar/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
|
xmlconcat
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
<?xml version="1.1"?><foo/><bar/>
|
<?xml version="1.1"?><foo/><bar/>
|
||||||
(1 row)
|
(1 row)
|
||||||
@ -205,23 +211,48 @@ SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
|
|||||||
xmlroot
|
xmlroot
|
||||||
---------
|
---------
|
||||||
<foo/>
|
<foo/>
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT xmlroot(xml '<foo/>', version '2.0');
|
SELECT xmlroot(xml '<foo/>', version '2.0');
|
||||||
xmlroot
|
xmlroot
|
||||||
-----------------------
|
-----------------------------
|
||||||
<?xml version="2.0"?>
|
<?xml version="2.0"?><foo/>
|
||||||
<foo/>
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
|
||||||
|
xmlroot
|
||||||
|
----------------------------------------------
|
||||||
|
<?xml version="1.0" standalone="yes"?><foo/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlroot(xml '<?xml version="1.1"?><foo/>', version no value, standalone yes);
|
||||||
|
xmlroot
|
||||||
|
----------------------------------------------
|
||||||
|
<?xml version="1.0" standalone="yes"?><foo/>
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
||||||
xmlroot
|
xmlroot
|
||||||
---------------------------------------
|
---------------------------------------------
|
||||||
<?xml version="1.1" standalone="no"?>
|
<?xml version="1.1" standalone="no"?><foo/>
|
||||||
<foo/>
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no);
|
||||||
|
xmlroot
|
||||||
|
---------------------------------------------
|
||||||
|
<?xml version="1.0" standalone="no"?><foo/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no value);
|
||||||
|
xmlroot
|
||||||
|
---------
|
||||||
|
<foo/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value);
|
||||||
|
xmlroot
|
||||||
|
----------------------------------------------
|
||||||
|
<?xml version="1.0" standalone="yes"?><foo/>
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT xmlroot (
|
SELECT xmlroot (
|
||||||
@ -240,10 +271,8 @@ SELECT xmlroot (
|
|||||||
standalone yes
|
standalone yes
|
||||||
);
|
);
|
||||||
xmlroot
|
xmlroot
|
||||||
----------------------------------------------------
|
------------------------------------------------------------------------------------------
|
||||||
<?xml version="1.0" standalone="yes"?>
|
<?xml version="1.0" standalone="yes"?><gazonk name="val" num="2"><qux>foo</qux></gazonk>
|
||||||
<gazonk name="val" num="2"><qux>foo</qux></gazonk>
|
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT xmlserialize(content data as character varying) FROM xmltest;
|
SELECT xmlserialize(content data as character varying) FROM xmltest;
|
||||||
@ -313,3 +342,29 @@ SELECT xmlpi(name "123");
|
|||||||
<?_x0031_23?>
|
<?_x0031_23?>
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
PREPARE foo (xml) AS SELECT xmlconcat('<foo/>', $1);
|
||||||
|
SET XML OPTION DOCUMENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
xmlconcat
|
||||||
|
--------------
|
||||||
|
<foo/><bar/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
EXECUTE foo ('bad');
|
||||||
|
ERROR: invalid XML document
|
||||||
|
DETAIL: Entity: line 1: parser error : Start tag expected, '<' not found
|
||||||
|
bad
|
||||||
|
^
|
||||||
|
SET XML OPTION CONTENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
xmlconcat
|
||||||
|
--------------
|
||||||
|
<foo/><bar/>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
EXECUTE foo ('good');
|
||||||
|
xmlconcat
|
||||||
|
------------
|
||||||
|
<foo/>good
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -30,11 +30,13 @@ ERROR: no XML support in this installation
|
|||||||
SELECT xmlconcat('hello', 'you');
|
SELECT xmlconcat('hello', 'you');
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlconcat(1, 2);
|
SELECT xmlconcat(1, 2);
|
||||||
ERROR: argument of XMLCONCAT must be type xml, not type integer
|
ERROR: argument of XMLCONCAT must be type "xml", not type integer
|
||||||
SELECT xmlconcat('bad', '<syntax');
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlelement(name element,
|
SELECT xmlelement(name element,
|
||||||
xmlattributes (1 as one, 'deuce' as two),
|
xmlattributes (1 as one, 'deuce' as two),
|
||||||
'content');
|
'content');
|
||||||
@ -92,8 +94,18 @@ SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
|
|||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlroot(xml '<foo/>', version '2.0');
|
SELECT xmlroot(xml '<foo/>', version '2.0');
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot(xml '<?xml version="1.1"?><foo/>', version no value, standalone yes);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no value);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlroot (
|
SELECT xmlroot (
|
||||||
xmlelement (
|
xmlelement (
|
||||||
name gazonk,
|
name gazonk,
|
||||||
@ -144,3 +156,15 @@ SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
|||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
SELECT xmlpi(name "123");
|
SELECT xmlpi(name "123");
|
||||||
ERROR: no XML support in this installation
|
ERROR: no XML support in this installation
|
||||||
|
PREPARE foo (xml) AS SELECT xmlconcat('<foo/>', $1);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SET XML OPTION DOCUMENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
ERROR: prepared statement "foo" does not exist
|
||||||
|
EXECUTE foo ('bad');
|
||||||
|
ERROR: prepared statement "foo" does not exist
|
||||||
|
SET XML OPTION CONTENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
ERROR: prepared statement "foo" does not exist
|
||||||
|
EXECUTE foo ('good');
|
||||||
|
ERROR: prepared statement "foo" does not exist
|
||||||
|
@ -25,6 +25,7 @@ SELECT xmlconcat('hello', 'you');
|
|||||||
SELECT xmlconcat(1, 2);
|
SELECT xmlconcat(1, 2);
|
||||||
SELECT xmlconcat('bad', '<syntax');
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
|
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
|
||||||
|
|
||||||
|
|
||||||
SELECT xmlelement(name element,
|
SELECT xmlelement(name element,
|
||||||
@ -69,7 +70,13 @@ SELECT xmlpi(name foo, ' bar');
|
|||||||
|
|
||||||
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
|
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
|
||||||
SELECT xmlroot(xml '<foo/>', version '2.0');
|
SELECT xmlroot(xml '<foo/>', version '2.0');
|
||||||
|
SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
|
||||||
|
SELECT xmlroot(xml '<?xml version="1.1"?><foo/>', version no value, standalone yes);
|
||||||
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no);
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no value);
|
||||||
|
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value);
|
||||||
|
|
||||||
|
|
||||||
SELECT xmlroot (
|
SELECT xmlroot (
|
||||||
xmlelement (
|
xmlelement (
|
||||||
@ -107,3 +114,14 @@ SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp;
|
|||||||
|
|
||||||
SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
||||||
SELECT xmlpi(name "123");
|
SELECT xmlpi(name "123");
|
||||||
|
|
||||||
|
|
||||||
|
PREPARE foo (xml) AS SELECT xmlconcat('<foo/>', $1);
|
||||||
|
|
||||||
|
SET XML OPTION DOCUMENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
EXECUTE foo ('bad');
|
||||||
|
|
||||||
|
SET XML OPTION CONTENT;
|
||||||
|
EXECUTE foo ('<bar/>');
|
||||||
|
EXECUTE foo ('good');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user