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 2232 of file xml.c.

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

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

2233 {
2235  const char *p;
2236 
2237  initStringInfo(&buf);
2238  for (p = str; *p; p++)
2239  {
2240  switch (*p)
2241  {
2242  case '&':
2243  appendStringInfoString(&buf, "&");
2244  break;
2245  case '<':
2246  appendStringInfoString(&buf, "&lt;");
2247  break;
2248  case '>':
2249  appendStringInfoString(&buf, "&gt;");
2250  break;
2251  case '\r':
2252  appendStringInfoString(&buf, "&#x0d;");
2253  break;
2254  default:
2255  appendStringInfoCharMacro(&buf, *p);
2256  break;
2257  }
2258  }
2259  return buf.data;
2260 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:127
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
char* map_sql_identifier_to_xml_name ( char *  ident,
bool  fully_escaped,
bool  escape_period 
)

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

1899 {
1900 #ifdef USE_LIBXML
1902  char *p;
1903 
1904  /*
1905  * SQL/XML doesn't make use of this case anywhere, so it's probably a
1906  * mistake.
1907  */
1908  Assert(fully_escaped || !escape_period);
1909 
1910  initStringInfo(&buf);
1911 
1912  for (p = ident; *p; p += pg_mblen(p))
1913  {
1914  if (*p == ':' && (p == ident || fully_escaped))
1915  appendStringInfoString(&buf, "_x003A_");
1916  else if (*p == '_' && *(p + 1) == 'x')
1917  appendStringInfoString(&buf, "_x005F_");
1918  else if (fully_escaped && p == ident &&
1919  pg_strncasecmp(p, "xml", 3) == 0)
1920  {
1921  if (*p == 'x')
1922  appendStringInfoString(&buf, "_x0078_");
1923  else
1924  appendStringInfoString(&buf, "_x0058_");
1925  }
1926  else if (escape_period && *p == '.')
1927  appendStringInfoString(&buf, "_x002E_");
1928  else
1929  {
1930  pg_wchar u = sqlchar_to_unicode(p);
1931 
1932  if ((p == ident)
1933  ? !is_valid_xml_namefirst(u)
1934  : !is_valid_xml_namechar(u))
1935  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
1936  else
1937  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1938  }
1939  }
1940 
1941  return buf.data;
1942 #else /* not USE_LIBXML */
1943  NO_XML_SUPPORT();
1944  return NULL;
1945 #endif /* not USE_LIBXML */
1946 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
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:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#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:208
char* map_sql_value_to_xml_value ( Datum  value,
Oid  type,
bool  xml_escape_strings 
)

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

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

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

Referenced by get_rule_expr().

1974 {
1976  char *p;
1977 
1978  initStringInfo(&buf);
1979 
1980  for (p = name; *p; p += pg_mblen(p))
1981  {
1982  if (*p == '_' && *(p + 1) == 'x'
1983  && isxdigit((unsigned char) *(p + 2))
1984  && isxdigit((unsigned char) *(p + 3))
1985  && isxdigit((unsigned char) *(p + 4))
1986  && isxdigit((unsigned char) *(p + 5))
1987  && *(p + 6) == '_')
1988  {
1989  unsigned int u;
1990 
1991  sscanf(p + 2, "%X", &u);
1993  p += 6;
1994  }
1995  else
1996  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1997  }
1998 
1999  return buf.data;
2000 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:208
static char * unicode_to_sqlchar(pg_wchar c)
Definition: xml.c:1953
bool pg_xml_error_occurred ( PgXmlErrorContext errcxt)
void pg_xml_init_library ( void  )
bool xml_is_document ( xmltype arg)

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

887 {
888 #ifdef USE_LIBXML
889  bool result;
890  volatile xmlDocPtr doc = NULL;
892 
893  /* We want to catch ereport(INVALID_XML_DOCUMENT) and return false */
894  PG_TRY();
895  {
896  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
898  result = true;
899  }
900  PG_CATCH();
901  {
902  ErrorData *errdata;
903  MemoryContext ecxt;
904 
905  ecxt = MemoryContextSwitchTo(ccxt);
906  errdata = CopyErrorData();
907  if (errdata->sqlerrcode == ERRCODE_INVALID_XML_DOCUMENT)
908  {
909  FlushErrorState();
910  result = false;
911  }
912  else
913  {
914  MemoryContextSwitchTo(ecxt);
915  PG_RE_THROW();
916  }
917  }
918  PG_END_TRY();
919 
920  if (doc)
921  xmlFreeDoc(doc);
922 
923  return result;
924 #else /* not USE_LIBXML */
925  NO_XML_SUPPORT();
926  return false;
927 #endif /* not USE_LIBXML */
928 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
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:1633
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 510 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().

511 {
512 #ifdef USE_LIBXML
513  int global_standalone = 1;
514  xmlChar *global_version = NULL;
515  bool global_version_no_value = false;
517  ListCell *v;
518 
519  initStringInfo(&buf);
520  foreach(v, args)
521  {
523  size_t len;
524  xmlChar *version;
525  int standalone;
526  char *str;
527 
528  len = VARSIZE(x) - VARHDRSZ;
529  str = text_to_cstring((text *) x);
530 
531  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
532 
533  if (standalone == 0 && global_standalone == 1)
534  global_standalone = 0;
535  if (standalone < 0)
536  global_standalone = -1;
537 
538  if (!version)
539  global_version_no_value = true;
540  else if (!global_version)
541  global_version = version;
542  else if (xmlStrcmp(version, global_version) != 0)
543  global_version_no_value = true;
544 
545  appendStringInfoString(&buf, str + len);
546  pfree(str);
547  }
548 
549  if (!global_version_no_value || global_standalone >= 0)
550  {
551  StringInfoData buf2;
552 
553  initStringInfo(&buf2);
554 
555  print_xml_decl(&buf2,
556  (!global_version_no_value) ? global_version : NULL,
557  0,
558  global_standalone);
559 
560  appendStringInfoString(&buf2, buf.data);
561  buf = buf2;
562  }
563 
564  return stringinfo_to_xmltype(&buf);
565 #else
566  NO_XML_SUPPORT();
567  return NULL;
568 #endif
569 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#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:157
static char * buf
Definition: pg_test_fsync.c:66
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#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:445
Definition: c.h:439
xmltype* xmlelement ( XmlExpr xexpr,
Datum named_argvalue,
bool named_argnull,
Datum argvalue,
bool argnull 
)

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

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

References GetDatabaseEncoding(), NO_XML_SUPPORT, and NULL.

Referenced by ExecEvalXmlExpr(), and texttoxml().

751 {
752 #ifdef USE_LIBXML
753  xmlDocPtr doc;
754 
755  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
757  xmlFreeDoc(doc);
758 
759  return (xmltype *) data;
760 #else
761  NO_XML_SUPPORT();
762  return NULL;
763 #endif
764 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
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 768 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().

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

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

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

Definition at line 613 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

614 {
615  if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data))
616  ereport(ERROR,
617  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
618  errmsg("not an XML document")));
619 
620  /* It's actually binary compatible, save for the above check. */
621  return (text *) data;
622 }
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:886
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 205 of file xml.c.

Referenced by ExecInitTableFuncScan().