mirror of https://github.com/postgres/postgres
Add support for converting binary values (i.e. bytea) into xml values,
with new GUC parameter "xmlbinary" that controls the output encoding, as per SQL/XML standard.
This commit is contained in:
parent
5b4a08896b
commit
4b48ad4fb2
|
@ -1,4 +1,4 @@
|
|||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.102 2007/01/16 18:26:02 alvherre Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.103 2007/01/19 16:58:45 petere Exp $ -->
|
||||
|
||||
<chapter Id="runtime-config">
|
||||
<title>Server Configuration</title>
|
||||
|
@ -3502,6 +3502,33 @@ SELECT * FROM parent WHERE key = 2400;
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="guc-xmlbinary" xreflabel="xmlbinary">
|
||||
<term><varname>xmlbinary</varname> (<type>string</type>)</term>
|
||||
<indexterm>
|
||||
<primary><varname>xmlbinary</> configuration parameter</primary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets how binary values are to be encoded in XML. This applies
|
||||
for example when <type>bytea</type> values are converted to
|
||||
XML by the functions <function>xmlelement</function> or
|
||||
<function>xmlforest</function>. Possible values are
|
||||
<literal>base64</literal> and <literal>hex</literal>, which
|
||||
are both defined in the XML Schema standard. The default is
|
||||
<literal>base64</literal>. For further information about
|
||||
XML-related functions, see <xref linkend="functions-xml">.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The actual choice here is mostly a matter of taste,
|
||||
constrained only by possible restrictions in client
|
||||
applications. Both methods support all possible values,
|
||||
although the hex encoding will be somewhat larger than the
|
||||
base64 encoding.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="runtime-config-client-format">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.18 2007/01/18 13:59:11 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.19 2007/01/19 16:58:46 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -73,6 +73,8 @@ static xmlDocPtr xml_parse(text *data, bool is_document, bool preserve_whitespac
|
|||
|
||||
#endif /* USE_LIBXML */
|
||||
|
||||
XmlBinaryType xmlbinary;
|
||||
|
||||
#define NO_XML_SUPPORT() \
|
||||
ereport(ERROR, \
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
|
||||
|
@ -1500,6 +1502,28 @@ map_sql_value_to_xml_value(Datum value, Oid type)
|
|||
if (type == XMLOID)
|
||||
return str;
|
||||
|
||||
#ifdef USE_LIBXML
|
||||
if (type == BYTEAOID)
|
||||
{
|
||||
xmlBufferPtr buf;
|
||||
xmlTextWriterPtr writer;
|
||||
char *result;
|
||||
|
||||
buf = xmlBufferCreate();
|
||||
writer = xmlNewTextWriterMemory(buf, 0);
|
||||
|
||||
if (xmlbinary == XMLBINARY_BASE64)
|
||||
xmlTextWriterWriteBase64(writer, VARDATA(value), 0, VARSIZE(value) - VARHDRSZ);
|
||||
else
|
||||
xmlTextWriterWriteBinHex(writer, VARDATA(value), 0, VARSIZE(value) - VARHDRSZ);
|
||||
|
||||
xmlFreeTextWriter(writer);
|
||||
result = pstrdup((const char *) xmlBufferContent(buf));
|
||||
xmlBufferFree(buf);
|
||||
return result;
|
||||
}
|
||||
#endif /* USE_LIBXML */
|
||||
|
||||
for (p = str; *p; p += pg_mblen(p))
|
||||
{
|
||||
switch (*p)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.368 2007/01/16 18:26:02 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.369 2007/01/19 16:58:46 petere Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -61,6 +61,7 @@
|
|||
#include "utils/pg_locale.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "utils/tzparser.h"
|
||||
#include "utils/xml.h"
|
||||
|
||||
#ifndef PG_KRB_SRVTAB
|
||||
#define PG_KRB_SRVTAB ""
|
||||
|
@ -142,6 +143,7 @@ static bool assign_transaction_read_only(bool newval, bool doit, GucSource sourc
|
|||
static const char *assign_canonical_path(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_xmlbinary(const char *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);
|
||||
|
@ -229,6 +231,7 @@ static char *timezone_abbreviations_string;
|
|||
static char *XactIsoLevel_string;
|
||||
static char *data_directory;
|
||||
static char *custom_variable_classes;
|
||||
static char *xmlbinary_string;
|
||||
static int max_function_args;
|
||||
static int max_index_keys;
|
||||
static int max_identifier_length;
|
||||
|
@ -2279,6 +2282,15 @@ static struct config_string ConfigureNamesString[] =
|
|||
NULL, assign_canonical_path, NULL
|
||||
},
|
||||
|
||||
{
|
||||
{"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
||||
gettext_noop("Sets how binary values are to be encoded in XML."),
|
||||
gettext_noop("Valid values are BASE64 and HEX.")
|
||||
},
|
||||
&xmlbinary_string,
|
||||
"base64", assign_xmlbinary, NULL
|
||||
},
|
||||
|
||||
/* End-of-list marker */
|
||||
{
|
||||
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
|
||||
|
@ -6475,6 +6487,24 @@ pg_timezone_abbrev_initialize(void)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
assign_xmlbinary(const char *newval, bool doit, GucSource source)
|
||||
{
|
||||
XmlBinaryType xb;
|
||||
|
||||
if (pg_strcasecmp(newval, "base64") == 0)
|
||||
xb = XMLBINARY_BASE64;
|
||||
else if (pg_strcasecmp(newval, "hex") == 0)
|
||||
xb = XMLBINARY_HEX;
|
||||
else
|
||||
return NULL; /* reject */
|
||||
|
||||
if (doit)
|
||||
xmlbinary = xb;
|
||||
|
||||
return newval;
|
||||
}
|
||||
|
||||
static bool
|
||||
assign_tcp_keepalives_idle(int newval, bool doit, GucSource source)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.10 2007/01/14 13:11:54 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.11 2007/01/19 16:58:46 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -43,4 +43,12 @@ extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
|
|||
extern char *map_xml_name_to_sql_identifier(char *name);
|
||||
extern char *map_sql_value_to_xml_value(Datum value, Oid type);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XMLBINARY_BASE64,
|
||||
XMLBINARY_HEX
|
||||
} XmlBinaryType;
|
||||
|
||||
extern XmlBinaryType xmlbinary;
|
||||
|
||||
#endif /* XML_H */
|
||||
|
|
|
@ -121,6 +121,20 @@ SELECT xmlelement(name foo, array[1, 2, 3]);
|
|||
<foo><element>1</element><element>2</element><element>3</element></foo>
|
||||
(1 row)
|
||||
|
||||
SET xmlbinary TO base64;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
xmlelement
|
||||
-----------------
|
||||
<foo>YmFy</foo>
|
||||
(1 row)
|
||||
|
||||
SET xmlbinary TO hex;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
xmlelement
|
||||
-------------------
|
||||
<foo>626172</foo>
|
||||
(1 row)
|
||||
|
||||
SELECT xmlparse(content 'abc');
|
||||
xmlparse
|
||||
----------
|
||||
|
|
|
@ -58,6 +58,12 @@ SELECT xmlelement(name foo, xml 'b<a/>r');
|
|||
ERROR: no XML support in this installation
|
||||
SELECT xmlelement(name foo, array[1, 2, 3]);
|
||||
ERROR: no XML support in this installation
|
||||
SET xmlbinary TO base64;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
ERROR: no XML support in this installation
|
||||
SET xmlbinary TO hex;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
ERROR: no XML support in this installation
|
||||
SELECT xmlparse(content 'abc');
|
||||
ERROR: no XML support in this installation
|
||||
SELECT xmlparse(content '<abc>x</abc>');
|
||||
|
|
|
@ -45,6 +45,10 @@ SELECT xmlelement(name foo, xml 'bar');
|
|||
SELECT xmlelement(name foo, text 'b<a/>r');
|
||||
SELECT xmlelement(name foo, xml 'b<a/>r');
|
||||
SELECT xmlelement(name foo, array[1, 2, 3]);
|
||||
SET xmlbinary TO base64;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
SET xmlbinary TO hex;
|
||||
SELECT xmlelement(name foo, bytea 'bar');
|
||||
|
||||
|
||||
SELECT xmlparse(content 'abc');
|
||||
|
|
Loading…
Reference in New Issue