77 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
10- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.77 2008/09/16 00 :49:41 tgl Exp $
10+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.78 2008/10/09 15 :49:04 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -1568,8 +1568,6 @@ map_sql_value_to_xml_value(Datum value, Oid type)
15681568{
15691569StringInfoData buf ;
15701570
1571- initStringInfo (& buf );
1572-
15731571if (type_is_array (type ))
15741572{
15751573ArrayType * array ;
@@ -1591,6 +1589,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
15911589& elem_values ,& elem_nulls ,
15921590& num_elems );
15931591
1592+ initStringInfo (& buf );
1593+
15941594for (i = 0 ;i < num_elems ;i ++ )
15951595{
15961596if (elem_nulls [i ])
@@ -1604,6 +1604,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
16041604
16051605pfree (elem_values );
16061606pfree (elem_nulls );
1607+
1608+ return buf .data ;
16071609}
16081610else
16091611{
@@ -1687,62 +1689,73 @@ map_sql_value_to_xml_value(Datum value, Oid type)
16871689
16881690return pstrdup (buf );
16891691}
1692+
1693+ #ifdef USE_LIBXML
1694+ case BYTEAOID :
1695+ {
1696+ bytea * bstr = DatumGetByteaPP (value );
1697+ xmlBufferPtr buf ;
1698+ xmlTextWriterPtr writer ;
1699+ char * result ;
1700+
1701+ xml_init ();
1702+
1703+ buf = xmlBufferCreate ();
1704+ writer = xmlNewTextWriterMemory (buf ,0 );
1705+
1706+ if (xmlbinary == XMLBINARY_BASE64 )
1707+ xmlTextWriterWriteBase64 (writer ,VARDATA_ANY (bstr ),
1708+ 0 ,VARSIZE_ANY_EXHDR (bstr ));
1709+ else
1710+ xmlTextWriterWriteBinHex (writer ,VARDATA_ANY (bstr ),
1711+ 0 ,VARSIZE_ANY_EXHDR (bstr ));
1712+
1713+ xmlFreeTextWriter (writer );
1714+ result = pstrdup ((const char * )xmlBufferContent (buf ));
1715+ xmlBufferFree (buf );
1716+ return result ;
1717+ }
1718+ #endif /* USE_LIBXML */
1719+
16901720}
16911721
1722+ /*
1723+ * otherwise, just use the type's native text representation
1724+ */
16921725getTypeOutputInfo (type ,& typeOut ,& isvarlena );
16931726str = OidOutputFunctionCall (typeOut ,value );
16941727
1728+ /* ... exactly as-is for XML */
16951729if (type == XMLOID )
16961730return str ;
16971731
1698- #ifdef USE_LIBXML
1699- if (type == BYTEAOID )
1700- {
1701- xmlBufferPtr buf ;
1702- xmlTextWriterPtr writer ;
1703- char * result ;
1704-
1705- xml_init ();
1706-
1707- buf = xmlBufferCreate ();
1708- writer = xmlNewTextWriterMemory (buf ,0 );
1709-
1710- if (xmlbinary == XMLBINARY_BASE64 )
1711- xmlTextWriterWriteBase64 (writer ,VARDATA (value ),0 ,VARSIZE (value )- VARHDRSZ );
1712- else
1713- xmlTextWriterWriteBinHex (writer ,VARDATA (value ),0 ,VARSIZE (value )- VARHDRSZ );
1714-
1715- xmlFreeTextWriter (writer );
1716- result = pstrdup ((const char * )xmlBufferContent (buf ));
1717- xmlBufferFree (buf );
1718- return result ;
1719- }
1720- #endif /* USE_LIBXML */
1732+ /* otherwise, translate special characters as needed */
1733+ initStringInfo (& buf );
17211734
1722- for (p = str ;* p ;p += pg_mblen ( p ) )
1735+ for (p = str ;* p ;p ++ )
17231736{
17241737switch (* p )
17251738{
17261739case '&' :
1727- appendStringInfo (& buf ,"&" );
1740+ appendStringInfoString (& buf ,"&" );
17281741break ;
17291742case '<' :
1730- appendStringInfo (& buf ,"<" );
1743+ appendStringInfoString (& buf ,"<" );
17311744break ;
17321745case '>' :
1733- appendStringInfo (& buf ,">" );
1746+ appendStringInfoString (& buf ,">" );
17341747break ;
17351748case '\r' :
1736- appendStringInfo (& buf ,"
" );
1749+ appendStringInfoString (& buf ,"
" );
17371750break ;
17381751default :
1739- appendBinaryStringInfo (& buf ,p , pg_mblen ( p ) );
1752+ appendStringInfoCharMacro (& buf ,* p );
17401753break ;
17411754}
17421755}
1743- }
17441756
1745- return buf .data ;
1757+ return buf .data ;
1758+ }
17461759}
17471760
17481761