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 "executor/tablefunc.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 (XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
 
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
 
const TableFuncRoutine XmlTableRoutine
 

Macro Definition Documentation

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

Definition at line 50 of file xml.h.

Referenced by ExecEvalXmlExpr(), xmlconcat(), and XmlTableSetDocument().

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

Definition at line 53 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 51 of file xml.h.

Typedef Documentation

Definition at line 48 of file xml.h.

Definition at line 23 of file xml.h.

Enumeration Type Documentation

Enumerator
PG_XML_STRICTNESS_LEGACY 
PG_XML_STRICTNESS_WELLFORMED 
PG_XML_STRICTNESS_ALL 

Definition at line 39 of file xml.h.

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

Definition at line 33 of file xml.h.

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

Definition at line 25 of file xml.h.

Function Documentation

char* escape_xml ( const char *  str)

Definition at line 2228 of file xml.c.

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

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

2229 {
2231  const char *p;
2232 
2233  initStringInfo(&buf);
2234  for (p = str; *p; p++)
2235  {
2236  switch (*p)
2237  {
2238  case '&':
2239  appendStringInfoString(&buf, "&");
2240  break;
2241  case '<':
2242  appendStringInfoString(&buf, "&lt;");
2243  break;
2244  case '>':
2245  appendStringInfoString(&buf, "&gt;");
2246  break;
2247  case '\r':
2248  appendStringInfoString(&buf, "&#x0d;");
2249  break;
2250  default:
2251  appendStringInfoCharMacro(&buf, *p);
2252  break;
2253  }
2254  }
2255  return buf.data;
2256 }
#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 1893 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().

1895 {
1896 #ifdef USE_LIBXML
1898  char *p;
1899 
1900  /*
1901  * SQL/XML doesn't make use of this case anywhere, so it's probably a
1902  * mistake.
1903  */
1904  Assert(fully_escaped || !escape_period);
1905 
1906  initStringInfo(&buf);
1907 
1908  for (p = ident; *p; p += pg_mblen(p))
1909  {
1910  if (*p == ':' && (p == ident || fully_escaped))
1911  appendStringInfoString(&buf, "_x003A_");
1912  else if (*p == '_' && *(p + 1) == 'x')
1913  appendStringInfoString(&buf, "_x005F_");
1914  else if (fully_escaped && p == ident &&
1915  pg_strncasecmp(p, "xml", 3) == 0)
1916  {
1917  if (*p == 'x')
1918  appendStringInfoString(&buf, "_x0078_");
1919  else
1920  appendStringInfoString(&buf, "_x0058_");
1921  }
1922  else if (escape_period && *p == '.')
1923  appendStringInfoString(&buf, "_x002E_");
1924  else
1925  {
1926  pg_wchar u = sqlchar_to_unicode(p);
1927 
1928  if ((p == ident)
1929  ? !is_valid_xml_namefirst(u)
1930  : !is_valid_xml_namechar(u))
1931  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
1932  else
1933  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1934  }
1935  }
1936 
1937  return buf.data;
1938 #else /* not USE_LIBXML */
1939  NO_XML_SUPPORT();
1940  return NULL;
1941 #endif /* not USE_LIBXML */
1942 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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:229
#define Assert(condition)
Definition: c.h:675
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 2009 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(), result, 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 ExecEvalXmlExpr(), map_sql_value_to_xml_value(), SPI_sql_row_to_xmlelement(), and xmlelement().

2010 {
2011  if (type_is_array_domain(type))
2012  {
2013  ArrayType *array;
2014  Oid elmtype;
2015  int16 elmlen;
2016  bool elmbyval;
2017  char elmalign;
2018  int num_elems;
2019  Datum *elem_values;
2020  bool *elem_nulls;
2022  int i;
2023 
2024  array = DatumGetArrayTypeP(value);
2025  elmtype = ARR_ELEMTYPE(array);
2026  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2027 
2028  deconstruct_array(array, elmtype,
2029  elmlen, elmbyval, elmalign,
2030  &elem_values, &elem_nulls,
2031  &num_elems);
2032 
2033  initStringInfo(&buf);
2034 
2035  for (i = 0; i < num_elems; i++)
2036  {
2037  if (elem_nulls[i])
2038  continue;
2039  appendStringInfoString(&buf, "<element>");
2041  map_sql_value_to_xml_value(elem_values[i],
2042  elmtype, true));
2043  appendStringInfoString(&buf, "</element>");
2044  }
2045 
2046  pfree(elem_values);
2047  pfree(elem_nulls);
2048 
2049  return buf.data;
2050  }
2051  else
2052  {
2053  Oid typeOut;
2054  bool isvarlena;
2055  char *str;
2056 
2057  /*
2058  * Flatten domains; the special-case treatments below should apply to,
2059  * eg, domains over boolean not just boolean.
2060  */
2061  type = getBaseType(type);
2062 
2063  /*
2064  * Special XSD formatting for some data types
2065  */
2066  switch (type)
2067  {
2068  case BOOLOID:
2069  if (DatumGetBool(value))
2070  return "true";
2071  else
2072  return "false";
2073 
2074  case DATEOID:
2075  {
2076  DateADT date;
2077  struct pg_tm tm;
2078  char buf[MAXDATELEN + 1];
2079 
2080  date = DatumGetDateADT(value);
2081  /* XSD doesn't support infinite values */
2082  if (DATE_NOT_FINITE(date))
2083  ereport(ERROR,
2084  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2085  errmsg("date out of range"),
2086  errdetail("XML does not support infinite date values.")));
2088  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2090 
2091  return pstrdup(buf);
2092  }
2093 
2094  case TIMESTAMPOID:
2095  {
2097  struct pg_tm tm;
2098  fsec_t fsec;
2099  char buf[MAXDATELEN + 1];
2100 
2101  timestamp = DatumGetTimestamp(value);
2102 
2103  /* XSD doesn't support infinite values */
2104  if (TIMESTAMP_NOT_FINITE(timestamp))
2105  ereport(ERROR,
2106  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2107  errmsg("timestamp out of range"),
2108  errdetail("XML does not support infinite timestamp values.")));
2109  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2110  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2111  else
2112  ereport(ERROR,
2113  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2114  errmsg("timestamp out of range")));
2115 
2116  return pstrdup(buf);
2117  }
2118 
2119  case TIMESTAMPTZOID:
2120  {
2122  struct pg_tm tm;
2123  int tz;
2124  fsec_t fsec;
2125  const char *tzn = NULL;
2126  char buf[MAXDATELEN + 1];
2127 
2128  timestamp = DatumGetTimestamp(value);
2129 
2130  /* XSD doesn't support infinite values */
2131  if (TIMESTAMP_NOT_FINITE(timestamp))
2132  ereport(ERROR,
2133  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2134  errmsg("timestamp out of range"),
2135  errdetail("XML does not support infinite timestamp values.")));
2136  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2137  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2138  else
2139  ereport(ERROR,
2140  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2141  errmsg("timestamp out of range")));
2142 
2143  return pstrdup(buf);
2144  }
2145 
2146 #ifdef USE_LIBXML
2147  case BYTEAOID:
2148  {
2149  bytea *bstr = DatumGetByteaPP(value);
2150  PgXmlErrorContext *xmlerrcxt;
2151  volatile xmlBufferPtr buf = NULL;
2152  volatile xmlTextWriterPtr writer = NULL;
2153  char *result;
2154 
2155  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2156 
2157  PG_TRY();
2158  {
2159  buf = xmlBufferCreate();
2160  if (buf == NULL || xmlerrcxt->err_occurred)
2161  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2162  "could not allocate xmlBuffer");
2163  writer = xmlNewTextWriterMemory(buf, 0);
2164  if (writer == NULL || xmlerrcxt->err_occurred)
2165  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2166  "could not allocate xmlTextWriter");
2167 
2168  if (xmlbinary == XMLBINARY_BASE64)
2169  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2170  0, VARSIZE_ANY_EXHDR(bstr));
2171  else
2172  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2173  0, VARSIZE_ANY_EXHDR(bstr));
2174 
2175  /* we MUST do this now to flush data out to the buffer */
2176  xmlFreeTextWriter(writer);
2177  writer = NULL;
2178 
2179  result = pstrdup((const char *) xmlBufferContent(buf));
2180  }
2181  PG_CATCH();
2182  {
2183  if (writer)
2184  xmlFreeTextWriter(writer);
2185  if (buf)
2186  xmlBufferFree(buf);
2187 
2188  pg_xml_done(xmlerrcxt, true);
2189 
2190  PG_RE_THROW();
2191  }
2192  PG_END_TRY();
2193 
2194  xmlBufferFree(buf);
2195 
2196  pg_xml_done(xmlerrcxt, false);
2197 
2198  return result;
2199  }
2200 #endif /* USE_LIBXML */
2201 
2202  }
2203 
2204  /*
2205  * otherwise, just use the type's native text representation
2206  */
2207  getTypeOutputInfo(type, &typeOut, &isvarlena);
2208  str = OidOutputFunctionCall(typeOut, value);
2209 
2210  /* ... exactly as-is for XML, and when escaping is not wanted */
2211  if (type == XMLOID || !xml_escape_strings)
2212  return str;
2213 
2214  /* otherwise, translate special characters as needed */
2215  return escape_xml(str);
2216  }
2217 }
#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:521
signed short int16
Definition: c.h:255
#define DATEOID
Definition: pg_type.h:507
#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:347
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:1077
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:48
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
#define DatumGetByteaPP(X)
Definition: fmgr.h:255
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
static struct @114 value
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
void pfree(void *pointer)
Definition: mcxt.c:950
#define TIMESTAMPOID
Definition: pg_type.h:515
#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:399
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:372
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:229
#define PG_RE_THROW()
Definition: elog.h:314
#define BOOLOID
Definition: pg_type.h:288
int xmlbinary
Definition: xml.c:96
#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:2056
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: c.h:439
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
char * escape_xml(const char *str)
Definition: xml.c:2228
#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:2009
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 1969 of file xml.c.

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

Referenced by get_rule_expr().

1970 {
1972  char *p;
1973 
1974  initStringInfo(&buf);
1975 
1976  for (p = name; *p; p += pg_mblen(p))
1977  {
1978  if (*p == '_' && *(p + 1) == 'x'
1979  && isxdigit((unsigned char) *(p + 2))
1980  && isxdigit((unsigned char) *(p + 3))
1981  && isxdigit((unsigned char) *(p + 4))
1982  && isxdigit((unsigned char) *(p + 5))
1983  && *(p + 6) == '_')
1984  {
1985  unsigned int u;
1986 
1987  sscanf(p + 2, "%X", &u);
1989  p += 6;
1990  }
1991  else
1992  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1993  }
1994 
1995  return buf.data;
1996 }
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:1949
bool pg_xml_error_occurred ( PgXmlErrorContext errcxt)
void pg_xml_init_library ( void  )
bool xml_is_document ( xmltype arg)

Definition at line 882 of file xml.c.

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

Referenced by ExecEvalXmlExpr(), and xmltotext_with_xmloption().

883 {
884 #ifdef USE_LIBXML
885  bool result;
886  volatile xmlDocPtr doc = NULL;
888 
889  /* We want to catch ereport(INVALID_XML_DOCUMENT) and return false */
890  PG_TRY();
891  {
892  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
894  result = true;
895  }
896  PG_CATCH();
897  {
898  ErrorData *errdata;
899  MemoryContext ecxt;
900 
901  ecxt = MemoryContextSwitchTo(ccxt);
902  errdata = CopyErrorData();
903  if (errdata->sqlerrcode == ERRCODE_INVALID_XML_DOCUMENT)
904  {
905  FlushErrorState();
906  result = false;
907  }
908  else
909  {
910  MemoryContextSwitchTo(ecxt);
911  PG_RE_THROW();
912  }
913  }
914  PG_END_TRY();
915 
916  if (doc)
917  xmlFreeDoc(doc);
918 
919  return result;
920 #else /* not USE_LIBXML */
921  NO_XML_SUPPORT();
922  return false;
923 #endif /* not USE_LIBXML */
924 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
int sqlerrcode
Definition: elog.h:342
ErrorData * CopyErrorData(void)
Definition: elog.c:1497
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
return result
Definition: formatting.c:1618
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:229
#define PG_RE_THROW()
Definition: elog.h:314
Definition: c.h:439
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
xmltype* xmlconcat ( List args)

Definition at line 506 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 ExecEvalXmlExpr(), and xmlconcat2().

507 {
508 #ifdef USE_LIBXML
509  int global_standalone = 1;
510  xmlChar *global_version = NULL;
511  bool global_version_no_value = false;
513  ListCell *v;
514 
515  initStringInfo(&buf);
516  foreach(v, args)
517  {
519  size_t len;
520  xmlChar *version;
521  int standalone;
522  char *str;
523 
524  len = VARSIZE(x) - VARHDRSZ;
525  str = text_to_cstring((text *) x);
526 
527  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
528 
529  if (standalone == 0 && global_standalone == 1)
530  global_standalone = 0;
531  if (standalone < 0)
532  global_standalone = -1;
533 
534  if (!version)
535  global_version_no_value = true;
536  else if (!global_version)
537  global_version = version;
538  else if (xmlStrcmp(version, global_version) != 0)
539  global_version_no_value = true;
540 
541  appendStringInfoString(&buf, str + len);
542  pfree(str);
543  }
544 
545  if (!global_version_no_value || global_standalone >= 0)
546  {
547  StringInfoData buf2;
548 
549  initStringInfo(&buf2);
550 
551  print_xml_decl(&buf2,
552  (!global_version_no_value) ? global_version : NULL,
553  0,
554  global_standalone);
555 
556  appendStringInfoString(&buf2, buf.data);
557  buf = buf2;
558  }
559 
560  return stringinfo_to_xmltype(&buf);
561 #else
562  NO_XML_SUPPORT();
563  return NULL;
564 #endif
565 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#define VARSIZE(PTR)
Definition: postgres.h:304
#define PointerGetDatum(X)
Definition: postgres.h:562
#define VARHDRSZ
Definition: c.h:445
#define DatumGetXmlP(X)
Definition: xml.h:50
void pfree(void *pointer)
Definition: mcxt.c:950
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:229
#define lfirst(lc)
Definition: pg_list.h:106
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
Definition: c.h:439
xmltype* xmlelement ( XmlExpr xexpr,
Datum named_argvalue,
bool named_argnull,
Datum argvalue,
bool argnull 
)

Definition at line 622 of file xml.c.

References arg, XmlExpr::arg_names, XmlExpr::args, ERROR, exprType(), forboth, i, lappend(), lfirst, map_sql_value_to_xml_value(), XmlExpr::name, XmlExpr::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, result, strVal, and xml_ereport().

Referenced by ExecEvalXmlExpr().

625 {
626 #ifdef USE_LIBXML
627  xmltype *result;
628  List *named_arg_strings;
629  List *arg_strings;
630  int i;
631  ListCell *arg;
632  ListCell *narg;
633  PgXmlErrorContext *xmlerrcxt;
634  volatile xmlBufferPtr buf = NULL;
635  volatile xmlTextWriterPtr writer = NULL;
636 
637  /*
638  * All arguments are already evaluated, and their values are passed in the
639  * named_argvalue/named_argnull or argvalue/argnull arrays. This avoids
640  * issues if one of the arguments involves a call to some other function
641  * or subsystem that wants to use libxml on its own terms. We examine the
642  * original XmlExpr to identify the numbers and types of the arguments.
643  */
644  named_arg_strings = NIL;
645  i = 0;
646  foreach(arg, xexpr->named_args)
647  {
648  Expr *e = (Expr *) lfirst(arg);
649  char *str;
650 
651  if (named_argnull[i])
652  str = NULL;
653  else
654  str = map_sql_value_to_xml_value(named_argvalue[i],
655  exprType((Node *) e),
656  false);
657  named_arg_strings = lappend(named_arg_strings, str);
658  i++;
659  }
660 
661  arg_strings = NIL;
662  i = 0;
663  foreach(arg, xexpr->args)
664  {
665  Expr *e = (Expr *) lfirst(arg);
666  char *str;
667 
668  /* here we can just forget NULL elements immediately */
669  if (!argnull[i])
670  {
671  str = map_sql_value_to_xml_value(argvalue[i],
672  exprType((Node *) e),
673  true);
674  arg_strings = lappend(arg_strings, str);
675  }
676  i++;
677  }
678 
679  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
680 
681  PG_TRY();
682  {
683  buf = xmlBufferCreate();
684  if (buf == NULL || xmlerrcxt->err_occurred)
685  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
686  "could not allocate xmlBuffer");
687  writer = xmlNewTextWriterMemory(buf, 0);
688  if (writer == NULL || xmlerrcxt->err_occurred)
689  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
690  "could not allocate xmlTextWriter");
691 
692  xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
693 
694  forboth(arg, named_arg_strings, narg, xexpr->arg_names)
695  {
696  char *str = (char *) lfirst(arg);
697  char *argname = strVal(lfirst(narg));
698 
699  if (str)
700  xmlTextWriterWriteAttribute(writer,
701  (xmlChar *) argname,
702  (xmlChar *) str);
703  }
704 
705  foreach(arg, arg_strings)
706  {
707  char *str = (char *) lfirst(arg);
708 
709  xmlTextWriterWriteRaw(writer, (xmlChar *) str);
710  }
711 
712  xmlTextWriterEndElement(writer);
713 
714  /* we MUST do this now to flush data out to the buffer ... */
715  xmlFreeTextWriter(writer);
716  writer = NULL;
717 
718  result = xmlBuffer_to_xmltype(buf);
719  }
720  PG_CATCH();
721  {
722  if (writer)
723  xmlFreeTextWriter(writer);
724  if (buf)
725  xmlBufferFree(buf);
726 
727  pg_xml_done(xmlerrcxt, true);
728 
729  PG_RE_THROW();
730  }
731  PG_END_TRY();
732 
733  xmlBufferFree(buf);
734 
735  pg_xml_done(xmlerrcxt, false);
736 
737  return result;
738 #else
739  NO_XML_SUPPORT();
740  return NULL;
741 #endif
742 }
#define NIL
Definition: pg_list.h:69
#define NO_XML_SUPPORT()
Definition: xml.c:213
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
char * name
Definition: primnodes.h:1141
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
Definition: nodes.h:506
#define strVal(v)
Definition: value.h:54
return result
Definition: formatting.c:1618
List * arg_names
Definition: primnodes.h:1143
#define ERROR
Definition: elog.h:43
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
List * named_args
Definition: primnodes.h:1142
List * args
Definition: primnodes.h:1144
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define PG_RE_THROW()
Definition: elog.h:314
e
Definition: preproc-init.c:82
int i
void * arg
Definition: c.h:439
#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:2009
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 746 of file xml.c.

References GetDatabaseEncoding(), NO_XML_SUPPORT, and NULL.

Referenced by ExecEvalXmlExpr(), and texttoxml().

747 {
748 #ifdef USE_LIBXML
749  xmlDocPtr doc;
750 
751  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
753  xmlFreeDoc(doc);
754 
755  return (xmltype *) data;
756 #else
757  NO_XML_SUPPORT();
758  return NULL;
759 #endif
760 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define NULL
Definition: c.h:229
Definition: c.h:439
xmltype* xmlpi ( char *  target,
text arg,
bool  arg_is_null,
bool result_is_null 
)

Definition at line 764 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

765 {
766 #ifdef USE_LIBXML
767  xmltype *result;
769 
770  if (pg_strcasecmp(target, "xml") == 0)
771  ereport(ERROR,
772  (errcode(ERRCODE_SYNTAX_ERROR), /* really */
773  errmsg("invalid XML processing instruction"),
774  errdetail("XML processing instruction target name cannot be \"%s\".", target)));
775 
776  /*
777  * Following the SQL standard, the null check comes after the syntax check
778  * above.
779  */
780  *result_is_null = arg_is_null;
781  if (*result_is_null)
782  return NULL;
783 
784  initStringInfo(&buf);
785 
786  appendStringInfo(&buf, "<?%s", target);
787 
788  if (arg != NULL)
789  {
790  char *string;
791 
792  string = text_to_cstring(arg);
793  if (strstr(string, "?>") != NULL)
794  ereport(ERROR,
795  (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
796  errmsg("invalid XML processing instruction"),
797  errdetail("XML processing instruction cannot contain \"?>\".")));
798 
799  appendStringInfoChar(&buf, ' ');
800  appendStringInfoString(&buf, string + strspn(string, " "));
801  pfree(string);
802  }
803  appendStringInfoString(&buf, "?>");
804 
805  result = stringinfo_to_xmltype(&buf);
806  pfree(buf.data);
807  return result;
808 #else
809  NO_XML_SUPPORT();
810  return NULL;
811 #endif
812 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void pfree(void *pointer)
Definition: mcxt.c:950
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:229
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
Definition: c.h:439
xmltype* xmlroot ( xmltype data,
text version,
int  standalone 
)

Definition at line 816 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 ExecEvalXmlExpr().

817 {
818 #ifdef USE_LIBXML
819  char *str;
820  size_t len;
821  xmlChar *orig_version;
822  int orig_standalone;
824 
825  len = VARSIZE(data) - VARHDRSZ;
826  str = text_to_cstring((text *) data);
827 
828  parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
829 
830  if (version)
831  orig_version = xml_text2xmlChar(version);
832  else
833  orig_version = NULL;
834 
835  switch (standalone)
836  {
837  case XML_STANDALONE_YES:
838  orig_standalone = 1;
839  break;
840  case XML_STANDALONE_NO:
841  orig_standalone = 0;
842  break;
844  orig_standalone = -1;
845  break;
847  /* leave original value */
848  break;
849  }
850 
851  initStringInfo(&buf);
852  print_xml_decl(&buf, orig_version, 0, orig_standalone);
853  appendStringInfoString(&buf, str + len);
854 
855  return stringinfo_to_xmltype(&buf);
856 #else
857  NO_XML_SUPPORT();
858  return NULL;
859 #endif
860 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#define VARSIZE(PTR)
Definition: postgres.h:304
#define VARHDRSZ
Definition: c.h:445
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:229
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
Definition: c.h:439
text* xmltotext_with_xmloption ( xmltype data,
XmlOptionType  xmloption_arg 
)

Definition at line 609 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

610 {
611  if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data))
612  ereport(ERROR,
613  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
614  errmsg("not an XML document")));
615 
616  /* It's actually binary compatible, save for the above check. */
617  return (text *) data;
618 }
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:882
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:439

Variable Documentation

int xmlbinary

Definition at line 96 of file xml.c.

Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().

const TableFuncRoutine XmlTableRoutine

Definition at line 201 of file xml.c.

Referenced by ExecInitTableFuncScan().