mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
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:
@ -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');
|
||||
|
Reference in New Issue
Block a user