PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
xml.h File Reference
#include "fmgr.h"
#include "nodes/execnodes.h"
#include "nodes/primnodes.h"
Include dependency graph for xml.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DatumGetXmlP(X)   ((xmltype *) PG_DETOAST_DATUM(X))
 
#define XmlPGetDatum(X)   PointerGetDatum(X)
 
#define PG_GETARG_XML_P(n)   DatumGetXmlP(PG_GETARG_DATUM(n))
 
#define PG_RETURN_XML_P(x)   PG_RETURN_POINTER(x)
 

Typedefs

typedef struct varlena xmltype
 
typedef struct PgXmlErrorContext PgXmlErrorContext
 

Enumerations

enum  XmlStandaloneType { XML_STANDALONE_YES, XML_STANDALONE_NO, XML_STANDALONE_NO_VALUE, XML_STANDALONE_OMITTED }
 
enum  XmlBinaryType { XMLBINARY_BASE64, XMLBINARY_HEX }
 
enum  PgXmlStrictness { PG_XML_STRICTNESS_LEGACY, PG_XML_STRICTNESS_WELLFORMED, PG_XML_STRICTNESS_ALL }
 

Functions

void pg_xml_init_library (void)
 
PgXmlErrorContextpg_xml_init (PgXmlStrictness strictness)
 
void pg_xml_done (PgXmlErrorContext *errcxt, bool isError)
 
bool pg_xml_error_occurred (PgXmlErrorContext *errcxt)
 
void xml_ereport (PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
 
xmltypexmlconcat (List *args)
 
xmltypexmlelement (XmlExprState *xmlExpr, ExprContext *econtext)
 
xmltypexmlparse (text *data, XmlOptionType xmloption, bool preserve_whitespace)
 
xmltypexmlpi (char *target, text *arg, bool arg_is_null, bool *result_is_null)
 
xmltypexmlroot (xmltype *data, text *version, int standalone)
 
bool xml_is_document (xmltype *arg)
 
textxmltotext_with_xmloption (xmltype *data, XmlOptionType xmloption_arg)
 
char * escape_xml (const char *str)
 
char * map_sql_identifier_to_xml_name (char *ident, bool fully_escaped, bool escape_period)
 
char * map_xml_name_to_sql_identifier (char *name)
 
char * map_sql_value_to_xml_value (Datum value, Oid type, bool xml_escape_strings)
 

Variables

int xmlbinary
 
int xmloption
 

Macro Definition Documentation

#define DatumGetXmlP (   X)    ((xmltype *) PG_DETOAST_DATUM(X))

Definition at line 49 of file xml.h.

Referenced by ExecEvalXml(), and xmlconcat().

#define PG_GETARG_XML_P (   n)    DatumGetXmlP(PG_GETARG_DATUM(n))

Definition at line 52 of file xml.h.

Referenced by xml_out(), xml_send(), xmlconcat2(), xmlexists(), xmltotext(), xpath(), and xpath_exists().

#define XmlPGetDatum (   X)    PointerGetDatum(X)

Definition at line 50 of file xml.h.

Typedef Documentation

Definition at line 47 of file xml.h.

Definition at line 22 of file xml.h.

Enumeration Type Documentation

Enumerator
PG_XML_STRICTNESS_LEGACY 
PG_XML_STRICTNESS_WELLFORMED 
PG_XML_STRICTNESS_ALL 

Definition at line 38 of file xml.h.

39 {
40  PG_XML_STRICTNESS_LEGACY, /* ignore errors unless function result
41  * indicates error condition */
42  PG_XML_STRICTNESS_WELLFORMED, /* ignore non-parser messages */
43  PG_XML_STRICTNESS_ALL /* report all notices/warnings/errors */
PgXmlStrictness
Definition: xml.h:38
Enumerator
XMLBINARY_BASE64 
XMLBINARY_HEX 

Definition at line 32 of file xml.h.

33 {
XmlBinaryType
Definition: xml.h:32
Enumerator
XML_STANDALONE_YES 
XML_STANDALONE_NO 
XML_STANDALONE_NO_VALUE 
XML_STANDALONE_OMITTED 

Definition at line 24 of file xml.h.

Function Documentation

char* escape_xml ( const char *  str)

Definition at line 2170 of file xml.c.

References appendStringInfoCharMacro, appendStringInfoString(), buf, StringInfoData::data, and initStringInfo().

Referenced by ExplainProperty(), ExplainPropertyList(), and map_sql_value_to_xml_value().

2171 {
2173  const char *p;
2174 
2175  initStringInfo(&buf);
2176  for (p = str; *p; p++)
2177  {
2178  switch (*p)
2179  {
2180  case '&':
2181  appendStringInfoString(&buf, "&");
2182  break;
2183  case '<':
2184  appendStringInfoString(&buf, "&lt;");
2185  break;
2186  case '>':
2187  appendStringInfoString(&buf, "&gt;");
2188  break;
2189  case '\r':
2190  appendStringInfoString(&buf, "&#x0d;");
2191  break;
2192  default:
2193  appendStringInfoCharMacro(&buf, *p);
2194  break;
2195  }
2196  }
2197  return buf.data;
2198 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:135
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
char* map_sql_identifier_to_xml_name ( char *  ident,
bool  fully_escaped,
bool  escape_period 
)

Definition at line 1835 of file xml.c.

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert, buf, StringInfoData::data, initStringInfo(), NO_XML_SUPPORT, NULL, pg_mblen(), and pg_strncasecmp().

Referenced by database_to_xml_internal(), map_multipart_sql_identifier_to_xml_name(), map_sql_catalog_to_xmlschema_types(), map_sql_schema_to_xmlschema_types(), map_sql_table_to_xmlschema(), query_to_xml_internal(), schema_to_xml_internal(), SPI_sql_row_to_xmlelement(), and transformXmlExpr().

1837 {
1838 #ifdef USE_LIBXML
1840  char *p;
1841 
1842  /*
1843  * SQL/XML doesn't make use of this case anywhere, so it's probably a
1844  * mistake.
1845  */
1846  Assert(fully_escaped || !escape_period);
1847 
1848  initStringInfo(&buf);
1849 
1850  for (p = ident; *p; p += pg_mblen(p))
1851  {
1852  if (*p == ':' && (p == ident || fully_escaped))
1853  appendStringInfoString(&buf, "_x003A_");
1854  else if (*p == '_' && *(p + 1) == 'x')
1855  appendStringInfoString(&buf, "_x005F_");
1856  else if (fully_escaped && p == ident &&
1857  pg_strncasecmp(p, "xml", 3) == 0)
1858  {
1859  if (*p == 'x')
1860  appendStringInfoString(&buf, "_x0078_");
1861  else
1862  appendStringInfoString(&buf, "_x0058_");
1863  }
1864  else if (escape_period && *p == '.')
1865  appendStringInfoString(&buf, "_x002E_");
1866  else
1867  {
1868  pg_wchar u = sqlchar_to_unicode(p);
1869 
1870  if ((p == ident)
1871  ? !is_valid_xml_namefirst(u)
1872  : !is_valid_xml_namechar(u))
1873  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
1874  else
1875  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1876  }
1877  }
1878 
1879  return buf.data;
1880 #else /* not USE_LIBXML */
1881  NO_XML_SUPPORT();
1882  return NULL;
1883 #endif /* not USE_LIBXML */
1884 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
char* map_sql_value_to_xml_value ( Datum  value,
Oid  type,
bool  xml_escape_strings 
)

Definition at line 1951 of file xml.c.

References appendStringInfoString(), ARR_ELEMTYPE, BOOLOID, buf, BYTEAOID, StringInfoData::data, DATE_NOT_FINITE, DATEOID, DatumGetArrayTypeP, DatumGetBool, DatumGetByteaPP, DatumGetDateADT, DatumGetTimestamp, deconstruct_array(), EncodeDateOnly(), EncodeDateTime(), ereport, errcode(), errdetail(), errmsg(), ERROR, escape_xml(), get_typlenbyvalalign(), getBaseType(), getTypeOutputInfo(), i, initStringInfo(), j2date(), map_sql_value_to_xml_value(), MAXDATELEN, NULL, OidOutputFunctionCall(), pfree(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, POSTGRES_EPOCH_JDATE, pstrdup(), timestamp2tm(), TIMESTAMP_NOT_FINITE, TIMESTAMPOID, TIMESTAMPTZOID, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, type_is_array_domain, USE_XSD_DATES, VARDATA_ANY, VARSIZE_ANY_EXHDR, xml_ereport(), xmlbinary, XMLBINARY_BASE64, and XMLOID.

Referenced by ExecEvalXml(), map_sql_value_to_xml_value(), SPI_sql_row_to_xmlelement(), and xmlelement().

1952 {
1953  if (type_is_array_domain(type))
1954  {
1955  ArrayType *array;
1956  Oid elmtype;
1957  int16 elmlen;
1958  bool elmbyval;
1959  char elmalign;
1960  int num_elems;
1961  Datum *elem_values;
1962  bool *elem_nulls;
1964  int i;
1965 
1966  array = DatumGetArrayTypeP(value);
1967  elmtype = ARR_ELEMTYPE(array);
1968  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
1969 
1970  deconstruct_array(array, elmtype,
1971  elmlen, elmbyval, elmalign,
1972  &elem_values, &elem_nulls,
1973  &num_elems);
1974 
1975  initStringInfo(&buf);
1976 
1977  for (i = 0; i < num_elems; i++)
1978  {
1979  if (elem_nulls[i])
1980  continue;
1981  appendStringInfoString(&buf, "<element>");
1983  map_sql_value_to_xml_value(elem_values[i],
1984  elmtype, true));
1985  appendStringInfoString(&buf, "</element>");
1986  }
1987 
1988  pfree(elem_values);
1989  pfree(elem_nulls);
1990 
1991  return buf.data;
1992  }
1993  else
1994  {
1995  Oid typeOut;
1996  bool isvarlena;
1997  char *str;
1998 
1999  /*
2000  * Flatten domains; the special-case treatments below should apply to,
2001  * eg, domains over boolean not just boolean.
2002  */
2003  type = getBaseType(type);
2004 
2005  /*
2006  * Special XSD formatting for some data types
2007  */
2008  switch (type)
2009  {
2010  case BOOLOID:
2011  if (DatumGetBool(value))
2012  return "true";
2013  else
2014  return "false";
2015 
2016  case DATEOID:
2017  {
2018  DateADT date;
2019  struct pg_tm tm;
2020  char buf[MAXDATELEN + 1];
2021 
2022  date = DatumGetDateADT(value);
2023  /* XSD doesn't support infinite values */
2024  if (DATE_NOT_FINITE(date))
2025  ereport(ERROR,
2026  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2027  errmsg("date out of range"),
2028  errdetail("XML does not support infinite date values.")));
2030  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2032 
2033  return pstrdup(buf);
2034  }
2035 
2036  case TIMESTAMPOID:
2037  {
2039  struct pg_tm tm;
2040  fsec_t fsec;
2041  char buf[MAXDATELEN + 1];
2042 
2043  timestamp = DatumGetTimestamp(value);
2044 
2045  /* XSD doesn't support infinite values */
2046  if (TIMESTAMP_NOT_FINITE(timestamp))
2047  ereport(ERROR,
2048  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2049  errmsg("timestamp out of range"),
2050  errdetail("XML does not support infinite timestamp values.")));
2051  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2052  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2053  else
2054  ereport(ERROR,
2055  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2056  errmsg("timestamp out of range")));
2057 
2058  return pstrdup(buf);
2059  }
2060 
2061  case TIMESTAMPTZOID:
2062  {
2064  struct pg_tm tm;
2065  int tz;
2066  fsec_t fsec;
2067  const char *tzn = NULL;
2068  char buf[MAXDATELEN + 1];
2069 
2070  timestamp = DatumGetTimestamp(value);
2071 
2072  /* XSD doesn't support infinite values */
2073  if (TIMESTAMP_NOT_FINITE(timestamp))
2074  ereport(ERROR,
2075  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2076  errmsg("timestamp out of range"),
2077  errdetail("XML does not support infinite timestamp values.")));
2078  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2079  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2080  else
2081  ereport(ERROR,
2082  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2083  errmsg("timestamp out of range")));
2084 
2085  return pstrdup(buf);
2086  }
2087 
2088 #ifdef USE_LIBXML
2089  case BYTEAOID:
2090  {
2091  bytea *bstr = DatumGetByteaPP(value);
2092  PgXmlErrorContext *xmlerrcxt;
2093  volatile xmlBufferPtr buf = NULL;
2094  volatile xmlTextWriterPtr writer = NULL;
2095  char *result;
2096 
2097  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2098 
2099  PG_TRY();
2100  {
2101  buf = xmlBufferCreate();
2102  if (buf == NULL || xmlerrcxt->err_occurred)
2103  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2104  "could not allocate xmlBuffer");
2105  writer = xmlNewTextWriterMemory(buf, 0);
2106  if (writer == NULL || xmlerrcxt->err_occurred)
2107  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2108  "could not allocate xmlTextWriter");
2109 
2110  if (xmlbinary == XMLBINARY_BASE64)
2111  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2112  0, VARSIZE_ANY_EXHDR(bstr));
2113  else
2114  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2115  0, VARSIZE_ANY_EXHDR(bstr));
2116 
2117  /* we MUST do this now to flush data out to the buffer */
2118  xmlFreeTextWriter(writer);
2119  writer = NULL;
2120 
2121  result = pstrdup((const char *) xmlBufferContent(buf));
2122  }
2123  PG_CATCH();
2124  {
2125  if (writer)
2126  xmlFreeTextWriter(writer);
2127  if (buf)
2128  xmlBufferFree(buf);
2129 
2130  pg_xml_done(xmlerrcxt, true);
2131 
2132  PG_RE_THROW();
2133  }
2134  PG_END_TRY();
2135 
2136  xmlBufferFree(buf);
2137 
2138  pg_xml_done(xmlerrcxt, false);
2139 
2140  return result;
2141  }
2142 #endif /* USE_LIBXML */
2143 
2144  }
2145 
2146  /*
2147  * otherwise, just use the type's native text representation
2148  */
2149  getTypeOutputInfo(type, &typeOut, &isvarlena);
2150  str = OidOutputFunctionCall(typeOut, value);
2151 
2152  /* ... exactly as-is for XML, and when escaping is not wanted */
2153  if (type == XMLOID || !xml_escape_strings)
2154  return str;
2155 
2156  /* otherwise, translate special characters as needed */
2157  return escape_xml(str);
2158  }
2159 }
#define MAXDATELEN
Definition: datetime.h:203
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3884
#define TIMESTAMPTZOID
Definition: pg_type.h:513
signed short int16
Definition: c.h:252
static struct @76 value
#define DATEOID
Definition: pg_type.h:499
#define DatumGetDateADT(X)
Definition: date.h:52
#define type_is_array_domain(typid)
Definition: lsyscache.h:165
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2600
#define VARDATA_ANY(PTR)
Definition: postgres.h:349
int32 DateADT
Definition: date.h:22
int64 timestamp
int64 TimestampTz
Definition: timestamp.h:39
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:1989
char * pstrdup(const char *in)
Definition: mcxt.c:1165
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1757
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:47
int errcode(int sqlerrcode)
Definition: elog.c:575
#define DatumGetByteaPP(X)
Definition: fmgr.h:247
long date
Definition: pgtypes_date.h:8
Definition: pgtime.h:25
unsigned int Oid
Definition: postgres_ext.h:31
static struct pg_tm tm
Definition: localtime.c:103
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
void pfree(void *pointer)
Definition: mcxt.c:992
#define TIMESTAMPOID
Definition: pg_type.h:507
#define ERROR
Definition: elog.h:43
#define DATE_NOT_FINITE(j)
Definition: date.h:42
#define XMLOID
Definition: pg_type.h:359
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:65
int tm_mon
Definition: pgtime.h:31
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define DatumGetBool(X)
Definition: postgres.h:401
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3999
int32 fsec_t
Definition: timestamp.h:41
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
#define ereport(elevel, rest)
Definition: elog.h:122
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:317
int64 Timestamp
Definition: timestamp.h:38
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
uintptr_t Datum
Definition: postgres.h:374
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:226
#define PG_RE_THROW()
Definition: elog.h:314
#define BOOLOID
Definition: pg_type.h:288
int xmlbinary
Definition: xml.c:95
#define BYTEAOID
Definition: pg_type.h:292
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3475
#define USE_XSD_DATES
Definition: miscadmin.h:213
int tm_year
Definition: pgtime.h:32
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:2006
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:342
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: c.h:435
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
char * escape_xml(const char *str)
Definition: xml.c:2170
#define PG_TRY()
Definition: elog.h:284
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:1951
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2239
#define ARR_ELEMTYPE(a)
Definition: array.h:273
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:300
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
#define DatumGetTimestamp(X)
Definition: timestamp.h:27
#define DatumGetArrayTypeP(X)
Definition: array.h:242
char* map_xml_name_to_sql_identifier ( char *  name)

Definition at line 1911 of file xml.c.

References appendBinaryStringInfo(), appendStringInfoString(), buf, StringInfoData::data, initStringInfo(), pg_mblen(), and unicode_to_sqlchar().

Referenced by get_rule_expr().

1912 {
1914  char *p;
1915 
1916  initStringInfo(&buf);
1917 
1918  for (p = name; *p; p += pg_mblen(p))
1919  {
1920  if (*p == '_' && *(p + 1) == 'x'
1921  && isxdigit((unsigned char) *(p + 2))
1922  && isxdigit((unsigned char) *(p + 3))
1923  && isxdigit((unsigned char) *(p + 4))
1924  && isxdigit((unsigned char) *(p + 5))
1925  && *(p + 6) == '_')
1926  {
1927  unsigned int u;
1928 
1929  sscanf(p + 2, "%X", &u);
1931  p += 6;
1932  }
1933  else
1934  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1935  }
1936 
1937  return buf.data;
1938 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771
const char * name
Definition: encode.c:521
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
static char * unicode_to_sqlchar(pg_wchar c)
Definition: xml.c:1891
bool pg_xml_error_occurred ( PgXmlErrorContext errcxt)
void pg_xml_init_library ( void  )
void xml_ereport ( PgXmlErrorContext errcxt,
int  level,
int  sqlcode,
const char *  msg 
)
bool xml_is_document ( xmltype arg)

Definition at line 837 of file xml.c.

References CopyErrorData(), CurrentMemoryContext, FlushErrorState(), GetDatabaseEncoding(), MemoryContextSwitchTo(), NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, ErrorData::sqlerrcode, and XMLOPTION_DOCUMENT.

Referenced by ExecEvalXml(), and xmltotext_with_xmloption().

838 {
839 #ifdef USE_LIBXML
840  bool result;
841  volatile xmlDocPtr doc = NULL;
843 
844  /* We want to catch ereport(INVALID_XML_DOCUMENT) and return false */
845  PG_TRY();
846  {
847  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
849  result = true;
850  }
851  PG_CATCH();
852  {
853  ErrorData *errdata;
854  MemoryContext ecxt;
855 
856  ecxt = MemoryContextSwitchTo(ccxt);
857  errdata = CopyErrorData();
858  if (errdata->sqlerrcode == ERRCODE_INVALID_XML_DOCUMENT)
859  {
860  FlushErrorState();
861  result = false;
862  }
863  else
864  {
865  MemoryContextSwitchTo(ecxt);
866  PG_RE_THROW();
867  }
868  }
869  PG_END_TRY();
870 
871  if (doc)
872  xmlFreeDoc(doc);
873 
874  return result;
875 #else /* not USE_LIBXML */
876  NO_XML_SUPPORT();
877  return false;
878 #endif /* not USE_LIBXML */
879 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
int sqlerrcode
Definition: elog.h:342
ErrorData * CopyErrorData(void)
Definition: elog.c:1497
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1587
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:226
#define PG_RE_THROW()
Definition: elog.h:314
Definition: c.h:435
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
xmltype* xmlconcat ( List args)

Definition at line 461 of file xml.c.

References appendStringInfoString(), buf, StringInfoData::data, DatumGetXmlP, initStringInfo(), lfirst, NO_XML_SUPPORT, NULL, pfree(), PointerGetDatum, stringinfo_to_xmltype(), text_to_cstring(), VARHDRSZ, and VARSIZE.

Referenced by ExecEvalXml(), and xmlconcat2().

462 {
463 #ifdef USE_LIBXML
464  int global_standalone = 1;
465  xmlChar *global_version = NULL;
466  bool global_version_no_value = false;
468  ListCell *v;
469 
470  initStringInfo(&buf);
471  foreach(v, args)
472  {
474  size_t len;
475  xmlChar *version;
476  int standalone;
477  char *str;
478 
479  len = VARSIZE(x) - VARHDRSZ;
480  str = text_to_cstring((text *) x);
481 
482  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
483 
484  if (standalone == 0 && global_standalone == 1)
485  global_standalone = 0;
486  if (standalone < 0)
487  global_standalone = -1;
488 
489  if (!version)
490  global_version_no_value = true;
491  else if (!global_version)
492  global_version = version;
493  else if (xmlStrcmp(version, global_version) != 0)
494  global_version_no_value = true;
495 
496  appendStringInfoString(&buf, str + len);
497  pfree(str);
498  }
499 
500  if (!global_version_no_value || global_standalone >= 0)
501  {
502  StringInfoData buf2;
503 
504  initStringInfo(&buf2);
505 
506  print_xml_decl(&buf2,
507  (!global_version_no_value) ? global_version : NULL,
508  0,
509  global_standalone);
510 
511  appendStringInfoString(&buf2, buf.data);
512  buf = buf2;
513  }
514 
515  return stringinfo_to_xmltype(&buf);
516 #else
517  NO_XML_SUPPORT();
518  return NULL;
519 #endif
520 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
#define VARSIZE(PTR)
Definition: postgres.h:306
#define PointerGetDatum(X)
Definition: postgres.h:564
#define VARHDRSZ
Definition: c.h:441
#define DatumGetXmlP(X)
Definition: xml.h:49
void pfree(void *pointer)
Definition: mcxt.c:992
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
char * text_to_cstring(const text *t)
Definition: varlena.c:184
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:396
Definition: c.h:435
xmltype* xmlelement ( XmlExprState xmlExpr,
ExprContext econtext 
)

Definition at line 577 of file xml.c.

References arg, XmlExpr::arg_names, XmlExprState::args, ERROR, ExecEvalExpr, ExprState::expr, exprType(), forboth, i, lappend(), lfirst, map_sql_value_to_xml_value(), XmlExpr::name, XmlExprState::named_args, NIL, NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, strVal, value, xml_ereport(), and XmlExprState::xprstate.

Referenced by ExecEvalXml().

578 {
579 #ifdef USE_LIBXML
580  XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
581  xmltype *result;
582  List *named_arg_strings;
583  List *arg_strings;
584  int i;
585  ListCell *arg;
586  ListCell *narg;
587  PgXmlErrorContext *xmlerrcxt;
588  volatile xmlBufferPtr buf = NULL;
589  volatile xmlTextWriterPtr writer = NULL;
590 
591  /*
592  * We first evaluate all the arguments, then start up libxml and create
593  * the result. This avoids issues if one of the arguments involves a call
594  * to some other function or subsystem that wants to use libxml on its own
595  * terms.
596  */
597  named_arg_strings = NIL;
598  i = 0;
599  foreach(arg, xmlExpr->named_args)
600  {
601  ExprState *e = (ExprState *) lfirst(arg);
602  Datum value;
603  bool isnull;
604  char *str;
605 
606  value = ExecEvalExpr(e, econtext, &isnull);
607  if (isnull)
608  str = NULL;
609  else
610  str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr), false);
611  named_arg_strings = lappend(named_arg_strings, str);
612  i++;
613  }
614 
615  arg_strings = NIL;
616  foreach(arg, xmlExpr->args)
617  {
618  ExprState *e = (ExprState *) lfirst(arg);
619  Datum value;
620  bool isnull;
621  char *str;
622 
623  value = ExecEvalExpr(e, econtext, &isnull);
624  /* here we can just forget NULL elements immediately */
625  if (!isnull)
626  {
627  str = map_sql_value_to_xml_value(value,
628  exprType((Node *) e->expr), true);
629  arg_strings = lappend(arg_strings, str);
630  }
631  }
632 
633  /* now safe to run libxml */
634  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
635 
636  PG_TRY();
637  {
638  buf = xmlBufferCreate();
639  if (buf == NULL || xmlerrcxt->err_occurred)
640  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
641  "could not allocate xmlBuffer");
642  writer = xmlNewTextWriterMemory(buf, 0);
643  if (writer == NULL || xmlerrcxt->err_occurred)
644  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
645  "could not allocate xmlTextWriter");
646 
647  xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
648 
649  forboth(arg, named_arg_strings, narg, xexpr->arg_names)
650  {
651  char *str = (char *) lfirst(arg);
652  char *argname = strVal(lfirst(narg));
653 
654  if (str)
655  xmlTextWriterWriteAttribute(writer,
656  (xmlChar *) argname,
657  (xmlChar *) str);
658  }
659 
660  foreach(arg, arg_strings)
661  {
662  char *str = (char *) lfirst(arg);
663 
664  xmlTextWriterWriteRaw(writer, (xmlChar *) str);
665  }
666 
667  xmlTextWriterEndElement(writer);
668 
669  /* we MUST do this now to flush data out to the buffer ... */
670  xmlFreeTextWriter(writer);
671  writer = NULL;
672 
673  result = xmlBuffer_to_xmltype(buf);
674  }
675  PG_CATCH();
676  {
677  if (writer)
678  xmlFreeTextWriter(writer);
679  if (buf)
680  xmlBufferFree(buf);
681 
682  pg_xml_done(xmlerrcxt, true);
683 
684  PG_RE_THROW();
685  }
686  PG_END_TRY();
687 
688  xmlBufferFree(buf);
689 
690  pg_xml_done(xmlerrcxt, false);
691 
692  return result;
693 #else
694  NO_XML_SUPPORT();
695  return NULL;
696 #endif
697 }
ExprState xprstate
Definition: execnodes.h:976
#define NIL
Definition: pg_list.h:69
#define NO_XML_SUPPORT()
Definition: xml.c:168
static struct @76 value
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
char * name
Definition: primnodes.h:1119
List * args
Definition: execnodes.h:978
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:47
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
List * arg_names
Definition: primnodes.h:1121
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:598
static char * buf
Definition: pg_test_fsync.c:65
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
List * lappend(List *list, void *datum)
Definition: list.c:128
uintptr_t Datum
Definition: postgres.h:374
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
List * named_args
Definition: execnodes.h:977
#define PG_RE_THROW()
Definition: elog.h:314
e
Definition: preproc-init.c:82
int i
void * arg
Definition: c.h:435
#define PG_TRY()
Definition: elog.h:284
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:1951
Definition: pg_list.h:45
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:300
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
xmltype* xmlparse ( text data,
XmlOptionType  xmloption,
bool  preserve_whitespace 
)

Definition at line 701 of file xml.c.

References GetDatabaseEncoding(), NO_XML_SUPPORT, and NULL.

Referenced by ExecEvalXml(), and texttoxml().

702 {
703 #ifdef USE_LIBXML
704  xmlDocPtr doc;
705 
706  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
708  xmlFreeDoc(doc);
709 
710  return (xmltype *) data;
711 #else
712  NO_XML_SUPPORT();
713  return NULL;
714 #endif
715 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define NULL
Definition: c.h:226
Definition: c.h:435
xmltype* xmlpi ( char *  target,
text arg,
bool  arg_is_null,
bool result_is_null 
)

Definition at line 719 of file xml.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), buf, StringInfoData::data, ereport, errcode(), errdetail(), errmsg(), ERROR, initStringInfo(), NO_XML_SUPPORT, NULL, pfree(), pg_strcasecmp(), stringinfo_to_xmltype(), and text_to_cstring().

Referenced by ExecEvalXml().

720 {
721 #ifdef USE_LIBXML
722  xmltype *result;
724 
725  if (pg_strcasecmp(target, "xml") == 0)
726  ereport(ERROR,
727  (errcode(ERRCODE_SYNTAX_ERROR), /* really */
728  errmsg("invalid XML processing instruction"),
729  errdetail("XML processing instruction target name cannot be \"%s\".", target)));
730 
731  /*
732  * Following the SQL standard, the null check comes after the syntax check
733  * above.
734  */
735  *result_is_null = arg_is_null;
736  if (*result_is_null)
737  return NULL;
738 
739  initStringInfo(&buf);
740 
741  appendStringInfo(&buf, "<?%s", target);
742 
743  if (arg != NULL)
744  {
745  char *string;
746 
747  string = text_to_cstring(arg);
748  if (strstr(string, "?>") != NULL)
749  ereport(ERROR,
750  (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
751  errmsg("invalid XML processing instruction"),
752  errdetail("XML processing instruction cannot contain \"?>\".")));
753 
754  appendStringInfoChar(&buf, ' ');
755  appendStringInfoString(&buf, string + strspn(string, " "));
756  pfree(string);
757  }
758  appendStringInfoString(&buf, "?>");
759 
760  result = stringinfo_to_xmltype(&buf);
761  pfree(buf.data);
762  return result;
763 #else
764  NO_XML_SUPPORT();
765  return NULL;
766 #endif
767 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
int errcode(int sqlerrcode)
Definition: elog.c:575
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void pfree(void *pointer)
Definition: mcxt.c:992
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
int errdetail(const char *fmt,...)
Definition: elog.c:873
char string[11]
Definition: preproc-type.c:46
#define ereport(elevel, rest)
Definition: elog.h:122
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define NULL
Definition: c.h:226
char * text_to_cstring(const text *t)
Definition: varlena.c:184
int errmsg(const char *fmt,...)
Definition: elog.c:797
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:396
Definition: c.h:435
xmltype* xmlroot ( xmltype data,
text version,
int  standalone 
)

Definition at line 771 of file xml.c.

References appendStringInfoString(), buf, initStringInfo(), NO_XML_SUPPORT, NULL, stringinfo_to_xmltype(), text_to_cstring(), VARHDRSZ, VARSIZE, XML_STANDALONE_NO, XML_STANDALONE_NO_VALUE, XML_STANDALONE_OMITTED, and XML_STANDALONE_YES.

Referenced by ExecEvalXml().

772 {
773 #ifdef USE_LIBXML
774  char *str;
775  size_t len;
776  xmlChar *orig_version;
777  int orig_standalone;
779 
780  len = VARSIZE(data) - VARHDRSZ;
781  str = text_to_cstring((text *) data);
782 
783  parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
784 
785  if (version)
786  orig_version = xml_text2xmlChar(version);
787  else
788  orig_version = NULL;
789 
790  switch (standalone)
791  {
792  case XML_STANDALONE_YES:
793  orig_standalone = 1;
794  break;
795  case XML_STANDALONE_NO:
796  orig_standalone = 0;
797  break;
799  orig_standalone = -1;
800  break;
802  /* leave original value */
803  break;
804  }
805 
806  initStringInfo(&buf);
807  print_xml_decl(&buf, orig_version, 0, orig_standalone);
808  appendStringInfoString(&buf, str + len);
809 
810  return stringinfo_to_xmltype(&buf);
811 #else
812  NO_XML_SUPPORT();
813  return NULL;
814 #endif
815 }
#define NO_XML_SUPPORT()
Definition: xml.c:168
#define VARSIZE(PTR)
Definition: postgres.h:306
#define VARHDRSZ
Definition: c.h:441
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define NULL
Definition: c.h:226
char * text_to_cstring(const text *t)
Definition: varlena.c:184
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:396
Definition: c.h:435
text* xmltotext_with_xmloption ( xmltype data,
XmlOptionType  xmloption_arg 
)

Definition at line 564 of file xml.c.

References ereport, errcode(), errmsg(), ERROR, xml_is_document(), and XMLOPTION_DOCUMENT.

Referenced by ExecEvalXml().

565 {
566  if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data))
567  ereport(ERROR,
568  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
569  errmsg("not an XML document")));
570 
571  /* It's actually binary compatible, save for the above check. */
572  return (text *) data;
573 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool xml_is_document(xmltype *arg)
Definition: xml.c:837
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:435

Variable Documentation

int xmlbinary

Definition at line 95 of file xml.c.

Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().