Commit 4b48ad4f authored by Peter Eisentraut's avatar Peter Eisentraut

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.
parent 5b4a0889
<!-- $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"> <chapter Id="runtime-config">
<title>Server Configuration</title> <title>Server Configuration</title>
...@@ -3502,6 +3502,33 @@ SELECT * FROM parent WHERE key = 2400; ...@@ -3502,6 +3502,33 @@ SELECT * FROM parent WHERE key = 2400;
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</sect2> </sect2>
<sect2 id="runtime-config-client-format"> <sect2 id="runtime-config-client-format">
......
...@@ -7,7 +7,7 @@ ...@@ -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.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 ...@@ -73,6 +73,8 @@ static xmlDocPtr xml_parse(text *data, bool is_document, bool preserve_whitespac
#endif /* USE_LIBXML */ #endif /* USE_LIBXML */
XmlBinaryType xmlbinary;
#define NO_XML_SUPPORT() \ #define NO_XML_SUPPORT() \
ereport(ERROR, \ ereport(ERROR, \
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
...@@ -1500,6 +1502,28 @@ map_sql_value_to_xml_value(Datum value, Oid type) ...@@ -1500,6 +1502,28 @@ map_sql_value_to_xml_value(Datum value, Oid type)
if (type == XMLOID) if (type == XMLOID)
return str; 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)) for (p = str; *p; p += pg_mblen(p))
{ {
switch (*p) switch (*p)
......
...@@ -10,7 +10,7 @@ ...@@ -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.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 @@ ...@@ -61,6 +61,7 @@
#include "utils/pg_locale.h" #include "utils/pg_locale.h"
#include "utils/ps_status.h" #include "utils/ps_status.h"
#include "utils/tzparser.h" #include "utils/tzparser.h"
#include "utils/xml.h"
#ifndef PG_KRB_SRVTAB #ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB "" #define PG_KRB_SRVTAB ""
...@@ -142,6 +143,7 @@ static bool assign_transaction_read_only(bool newval, bool doit, GucSource sourc ...@@ -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_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_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 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);
...@@ -229,6 +231,7 @@ static char *timezone_abbreviations_string; ...@@ -229,6 +231,7 @@ static char *timezone_abbreviations_string;
static char *XactIsoLevel_string; 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 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;
...@@ -2279,6 +2282,15 @@ static struct config_string ConfigureNamesString[] = ...@@ -2279,6 +2282,15 @@ static struct config_string ConfigureNamesString[] =
NULL, assign_canonical_path, NULL 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 */ /* End-of-list marker */
{ {
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
...@@ -6475,6 +6487,24 @@ pg_timezone_abbrev_initialize(void) ...@@ -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 static bool
assign_tcp_keepalives_idle(int newval, bool doit, GucSource source) assign_tcp_keepalives_idle(int newval, bool doit, GucSource source)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -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.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); ...@@ -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_xml_name_to_sql_identifier(char *name);
extern char *map_sql_value_to_xml_value(Datum value, Oid type); 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 */ #endif /* XML_H */
...@@ -121,6 +121,20 @@ SELECT xmlelement(name foo, array[1, 2, 3]); ...@@ -121,6 +121,20 @@ SELECT xmlelement(name foo, array[1, 2, 3]);
<foo><element>1</element><element>2</element><element>3</element></foo> <foo><element>1</element><element>2</element><element>3</element></foo>
(1 row) (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'); SELECT xmlparse(content 'abc');
xmlparse xmlparse
---------- ----------
......
...@@ -58,6 +58,12 @@ SELECT xmlelement(name foo, xml 'b<a/>r'); ...@@ -58,6 +58,12 @@ SELECT xmlelement(name foo, xml 'b<a/>r');
ERROR: no XML support in this installation ERROR: no XML support in this installation
SELECT xmlelement(name foo, array[1, 2, 3]); SELECT xmlelement(name foo, array[1, 2, 3]);
ERROR: no XML support in this installation 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'); SELECT xmlparse(content 'abc');
ERROR: no XML support in this installation ERROR: no XML support in this installation
SELECT xmlparse(content '<abc>x</abc>'); SELECT xmlparse(content '<abc>x</abc>');
......
...@@ -45,6 +45,10 @@ SELECT xmlelement(name foo, xml 'bar'); ...@@ -45,6 +45,10 @@ SELECT xmlelement(name foo, xml 'bar');
SELECT xmlelement(name foo, text 'b<a/>r'); SELECT xmlelement(name foo, text 'b<a/>r');
SELECT xmlelement(name foo, xml 'b<a/>r'); SELECT xmlelement(name foo, xml 'b<a/>r');
SELECT xmlelement(name foo, array[1, 2, 3]); 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'); SELECT xmlparse(content 'abc');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment