PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
xml.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_class.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "executor/spi.h"
#include "executor/tablefunc.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xml.h"
Include dependency graph for xml.c:

Go to the source code of this file.

Macros

#define NO_XML_SUPPORT()
 
#define NAMESPACE_XSD   "http://www.w3.org/2001/XMLSchema"
 
#define NAMESPACE_XSI   "http://www.w3.org/2001/XMLSchema-instance"
 
#define NAMESPACE_SQLXML   "http://standards.iso.org/iso/9075/2003/sqlxml"
 
#define PG_XML_DEFAULT_VERSION   "1.0"
 
#define XML_VISIBLE_SCHEMAS_EXCLUDE   "(nspname ~ '^pg_' OR nspname = 'information_schema')"
 
#define XML_VISIBLE_SCHEMAS   "SELECT oid FROM pg_catalog.pg_namespace WHERE pg_catalog.has_schema_privilege (oid, 'USAGE') AND NOT " XML_VISIBLE_SCHEMAS_EXCLUDE
 

Functions

static void xmldata_root_element_start (StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
 
static void xmldata_root_element_end (StringInfo result, const char *eltname)
 
static StringInfo query_to_xml_internal (const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static const char * map_sql_table_to_xmlschema (TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_schema_to_xmlschema_types (Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_catalog_to_xmlschema_types (List *nspid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_type_to_xml_name (Oid typeoid, int typmod)
 
static const char * map_sql_typecoll_to_xmlschema_types (List *tupdesc_list)
 
static const char * map_sql_type_to_xmlschema_type (Oid typeoid, int typmod)
 
static void SPI_sql_row_to_xmlelement (uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static void XmlTableInitOpaque (struct TableFuncScanState *state, int natts)
 
static void XmlTableSetDocument (struct TableFuncScanState *state, Datum value)
 
static void XmlTableSetNamespace (struct TableFuncScanState *state, char *name, char *uri)
 
static void XmlTableSetRowFilter (struct TableFuncScanState *state, char *path)
 
static void XmlTableSetColumnFilter (struct TableFuncScanState *state, char *path, int colnum)
 
static bool XmlTableFetchRow (struct TableFuncScanState *state)
 
static Datum XmlTableGetValue (struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
 
static void XmlTableDestroyOpaque (struct TableFuncScanState *state)
 
Datum xml_in (PG_FUNCTION_ARGS)
 
static char * xml_out_internal (xmltype *x, pg_enc target_encoding)
 
Datum xml_out (PG_FUNCTION_ARGS)
 
Datum xml_recv (PG_FUNCTION_ARGS)
 
Datum xml_send (PG_FUNCTION_ARGS)
 
static xmltypestringinfo_to_xmltype (StringInfo buf)
 
static xmltypecstring_to_xmltype (const char *string)
 
Datum xmlcomment (PG_FUNCTION_ARGS)
 
xmltypexmlconcat (List *args)
 
Datum xmlconcat2 (PG_FUNCTION_ARGS)
 
Datum texttoxml (PG_FUNCTION_ARGS)
 
Datum xmltotext (PG_FUNCTION_ARGS)
 
textxmltotext_with_xmloption (xmltype *data, XmlOptionType xmloption_arg)
 
xmltypexmlelement (XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
 
xmltypexmlparse (text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
 
xmltypexmlpi (char *target, text *arg, bool arg_is_null, bool *result_is_null)
 
xmltypexmlroot (xmltype *data, text *version, int standalone)
 
Datum xmlvalidate (PG_FUNCTION_ARGS)
 
bool xml_is_document (xmltype *arg)
 
char * map_sql_identifier_to_xml_name (char *ident, bool fully_escaped, bool escape_period)
 
static char * unicode_to_sqlchar (pg_wchar c)
 
char * map_xml_name_to_sql_identifier (char *name)
 
char * map_sql_value_to_xml_value (Datum value, Oid type, bool xml_escape_strings)
 
char * escape_xml (const char *str)
 
static char * _SPI_strdup (const char *s)
 
static Listquery_to_oid_list (const char *query)
 
static Listschema_get_xml_visible_tables (Oid nspid)
 
static Listdatabase_get_xml_visible_schemas (void)
 
static Listdatabase_get_xml_visible_tables (void)
 
static StringInfo table_to_xml_internal (Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum table_to_xml (PG_FUNCTION_ARGS)
 
Datum query_to_xml (PG_FUNCTION_ARGS)
 
Datum cursor_to_xml (PG_FUNCTION_ARGS)
 
Datum table_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum cursor_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum table_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo schema_to_xml_internal (Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum schema_to_xml (PG_FUNCTION_ARGS)
 
static void xsd_schema_element_start (StringInfo result, const char *targetns)
 
static void xsd_schema_element_end (StringInfo result)
 
static StringInfo schema_to_xmlschema_internal (const char *schemaname, bool nulls, bool tableforest, const char *targetns)
 
Datum schema_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum schema_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xml_internal (const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xml (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xmlschema_internal (bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum database_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static char * map_multipart_sql_identifier_to_xml_name (char *a, char *b, char *c, char *d)
 
Datum xpath (PG_FUNCTION_ARGS)
 
Datum xmlexists (PG_FUNCTION_ARGS)
 
Datum xpath_exists (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed_document (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed_content (PG_FUNCTION_ARGS)
 

Variables

int xmlbinary
 
int xmloption
 
const TableFuncRoutine XmlTableRoutine
 

Macro Definition Documentation

#define NAMESPACE_SQLXML   "http://standards.iso.org/iso/9075/2003/sqlxml"

Definition at line 228 of file xml.c.

#define NAMESPACE_XSD   "http://www.w3.org/2001/XMLSchema"

Definition at line 226 of file xml.c.

Referenced by xsd_schema_element_start().

#define NAMESPACE_XSI   "http://www.w3.org/2001/XMLSchema-instance"

Definition at line 227 of file xml.c.

Referenced by xmldata_root_element_start().

#define NO_XML_SUPPORT ( )
Value:
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
errmsg("unsupported XML feature"), \
errdetail("This functionality requires the server to be built with libxml support."), \
errhint("You need to rebuild PostgreSQL using --with-libxml.")))
int errhint(const char *fmt,...)
Definition: elog.c:987
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

Definition at line 217 of file xml.c.

Referenced by map_sql_identifier_to_xml_name(), xml_in(), xml_is_document(), xml_is_well_formed(), xml_is_well_formed_content(), xml_is_well_formed_document(), xml_recv(), xmlcomment(), xmlconcat(), xmlelement(), xmlexists(), xmlparse(), xmlpi(), xmlroot(), XmlTableDestroyOpaque(), XmlTableFetchRow(), XmlTableGetValue(), XmlTableInitOpaque(), XmlTableSetColumnFilter(), XmlTableSetDocument(), XmlTableSetNamespace(), XmlTableSetRowFilter(), xpath(), and xpath_exists().

#define PG_XML_DEFAULT_VERSION   "1.0"

Definition at line 280 of file xml.c.

#define XML_VISIBLE_SCHEMAS   "SELECT oid FROM pg_catalog.pg_namespace WHERE pg_catalog.has_schema_privilege (oid, 'USAGE') AND NOT " XML_VISIBLE_SCHEMAS_EXCLUDE

Definition at line 2369 of file xml.c.

Referenced by database_get_xml_visible_schemas(), and database_get_xml_visible_tables().

#define XML_VISIBLE_SCHEMAS_EXCLUDE   "(nspname ~ '^pg_' OR nspname = 'information_schema')"

Definition at line 2367 of file xml.c.

Function Documentation

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2264 of file xml.c.

References SPI_palloc().

Referenced by cursor_to_xmlschema(), query_to_xml_and_xmlschema(), and query_to_xmlschema().

2265 {
2266  size_t len = strlen(s) + 1;
2267  char *ret = SPI_palloc(len);
2268 
2269  memcpy(ret, s, len);
2270  return ret;
2271 }
void * SPI_palloc(Size size)
Definition: spi.c:922
static xmltype* cstring_to_xmltype ( const char *  string)
static

Definition at line 452 of file xml.c.

References cstring_to_text().

Referenced by cursor_to_xmlschema(), query_to_xmlschema(), and table_to_xmlschema().

453 {
454  return (xmltype *) cstring_to_text(string);
455 }
text * cstring_to_text(const char *s)
Definition: varlena.c:149
Definition: c.h:439
Datum cursor_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2444 of file xml.c.

References appendStringInfoChar(), ereport, errcode(), errmsg(), ERROR, i, initStringInfo(), NULL, PG_GETARG_BOOL, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, result, SPI_connect(), SPI_cursor_fetch(), SPI_cursor_find(), SPI_finish(), SPI_processed, SPI_sql_row_to_xmlelement(), stringinfo_to_xmltype(), text_to_cstring(), xmldata_root_element_end(), and xmldata_root_element_start().

2445 {
2448  bool nulls = PG_GETARG_BOOL(2);
2449  bool tableforest = PG_GETARG_BOOL(3);
2450  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2451 
2453  Portal portal;
2454  uint64 i;
2455 
2456  initStringInfo(&result);
2457 
2458  if (!tableforest)
2459  {
2460  xmldata_root_element_start(&result, "table", NULL, targetns, true);
2461  appendStringInfoChar(&result, '\n');
2462  }
2463 
2464  SPI_connect();
2465  portal = SPI_cursor_find(name);
2466  if (portal == NULL)
2467  ereport(ERROR,
2468  (errcode(ERRCODE_UNDEFINED_CURSOR),
2469  errmsg("cursor \"%s\" does not exist", name)));
2470 
2471  SPI_cursor_fetch(portal, true, count);
2472  for (i = 0; i < SPI_processed; i++)
2473  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2474  tableforest, targetns, true);
2475 
2476  SPI_finish();
2477 
2478  if (!tableforest)
2479  xmldata_root_element_end(&result, "table");
2480 
2482 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2498
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
uint64 SPI_processed
Definition: spi.c:39
signed int int32
Definition: c.h:256
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1335
#define ERROR
Definition: elog.h:43
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#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
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2525
const char * name
Definition: encode.c:521
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
int i
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1347
static void SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3610
Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2625 of file xml.c.

References _SPI_strdup(), cstring_to_xmltype(), ereport, errcode(), errmsg(), ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, SPI_connect(), SPI_cursor_find(), SPI_finish(), text_to_cstring(), and PortalData::tupDesc.

2626 {
2628  bool nulls = PG_GETARG_BOOL(1);
2629  bool tableforest = PG_GETARG_BOOL(2);
2630  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2631  const char *xmlschema;
2632  Portal portal;
2633 
2634  SPI_connect();
2635  portal = SPI_cursor_find(name);
2636  if (portal == NULL)
2637  ereport(ERROR,
2638  (errcode(ERRCODE_UNDEFINED_CURSOR),
2639  errmsg("cursor \"%s\" does not exist", name)));
2640 
2641  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2642  InvalidOid, nulls,
2643  tableforest, targetns));
2644  SPI_finish();
2645 
2646  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
2647 }
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1335
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2264
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3043
#define ereport(elevel, rest)
Definition: elog.h:122
TupleDesc tupDesc
Definition: portal.h:155
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:452
#define NULL
Definition: c.h:229
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
static List* database_get_xml_visible_schemas ( void  )
static

Definition at line 2373 of file xml.c.

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

2374 {
2375  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2376 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2321
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2369
static List* database_get_xml_visible_tables ( void  )
static

Definition at line 2380 of file xml.c.

References CppAsString2, query_to_oid_list(), RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_VIEW, and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xmlschema_internal().

2381 {
2382  /* At the moment there is no order required here. */
2383  return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2384  " WHERE relkind IN ("
2388  " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2389  " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2390 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2321
#define RELKIND_MATVIEW
Definition: pg_class.h:165
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2369
#define CppAsString2(x)
Definition: c.h:162
#define RELKIND_VIEW
Definition: pg_class.h:164
#define RELKIND_RELATION
Definition: pg_class.h:160
Datum database_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2926 of file xml.c.

References database_to_xml_internal(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().

2927 {
2928  bool nulls = PG_GETARG_BOOL(0);
2929  bool tableforest = PG_GETARG_BOOL(1);
2930  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2931 
2933  tableforest, targetns)));
2934 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2883
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#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
Datum database_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2993 of file xml.c.

References StringInfoData::data, database_to_xml_internal(), database_to_xmlschema_internal(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().

2994 {
2995  bool nulls = PG_GETARG_BOOL(0);
2996  bool tableforest = PG_GETARG_BOOL(1);
2997  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2998  StringInfo xmlschema;
2999 
3000  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3001 
3003  nulls, tableforest, targetns)));
3004 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2883
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2938
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
static StringInfo database_to_xml_internal ( const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 2883 of file xml.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, database_get_xml_visible_schemas(), get_database_name(), lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), MyDatabaseId, NULL, result, schema_to_xml_internal(), SPI_connect(), SPI_finish(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by database_to_xml(), and database_to_xml_and_xmlschema().

2885 {
2887  List *nspid_list;
2888  ListCell *cell;
2889  char *xmlcn;
2890 
2892  true, false);
2893  result = makeStringInfo();
2894 
2895  xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
2896  appendStringInfoChar(result, '\n');
2897 
2898  if (xmlschema)
2899  appendStringInfo(result, "%s\n\n", xmlschema);
2900 
2901  SPI_connect();
2902 
2903  nspid_list = database_get_xml_visible_schemas();
2904 
2905  foreach(cell, nspid_list)
2906  {
2907  Oid nspid = lfirst_oid(cell);
2908  StringInfo subres;
2909 
2910  subres = schema_to_xml_internal(nspid, NULL, nulls,
2911  tableforest, targetns, false);
2912 
2913  appendStringInfoString(result, subres->data);
2914  appendStringInfoChar(result, '\n');
2915  }
2916 
2917  SPI_finish();
2918 
2919  xmldata_root_element_end(result, xmlcn);
2920 
2921  return result;
2922 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2498
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2708
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2373
Oid MyDatabaseId
Definition: globals.c:77
#define NULL
Definition: c.h:229
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2525
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2981 of file xml.c.

References database_to_xmlschema_internal(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().

2982 {
2983  bool nulls = PG_GETARG_BOOL(0);
2984  bool tableforest = PG_GETARG_BOOL(1);
2985  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2986 
2988  tableforest, targetns)));
2989 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2938
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
static StringInfo database_to_xmlschema_internal ( bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 2938 of file xml.c.

References AccessShareLock, appendStringInfoString(), CreateTupleDescCopy(), database_get_xml_visible_schemas(), database_get_xml_visible_tables(), heap_close, heap_open(), lappend(), lfirst_oid, makeStringInfo(), map_sql_catalog_to_xmlschema_types(), map_sql_typecoll_to_xmlschema_types(), NIL, NoLock, RelationData::rd_att, result, SPI_connect(), SPI_finish(), xsd_schema_element_end(), and xsd_schema_element_start().

Referenced by database_to_xml_and_xmlschema(), and database_to_xmlschema().

2940 {
2941  List *relid_list;
2942  List *nspid_list;
2943  List *tupdesc_list;
2944  ListCell *cell;
2946 
2947  result = makeStringInfo();
2948 
2949  xsd_schema_element_start(result, targetns);
2950 
2951  SPI_connect();
2952 
2953  relid_list = database_get_xml_visible_tables();
2954  nspid_list = database_get_xml_visible_schemas();
2955 
2956  tupdesc_list = NIL;
2957  foreach(cell, relid_list)
2958  {
2959  Relation rel;
2960 
2961  rel = heap_open(lfirst_oid(cell), AccessShareLock);
2962  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2963  heap_close(rel, NoLock);
2964  }
2965 
2966  appendStringInfoString(result,
2967  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2968 
2969  appendStringInfoString(result,
2970  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
2971 
2972  xsd_schema_element_end(result);
2973 
2974  SPI_finish();
2975 
2976  return result;
2977 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2773
#define NIL
Definition: pg_list.h:69
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
#define AccessShareLock
Definition: lockdefs.h:36
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3219
return result
Definition: formatting.c:1633
#define heap_close(r, l)
Definition: heapam.h:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:128
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3381
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2373
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2790
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
TupleDesc rd_att
Definition: rel.h:115
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2380
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, "&amp;");
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
static char* map_multipart_sql_identifier_to_xml_name ( char *  a,
char *  b,
char *  c,
char *  d 
)
static

Definition at line 3012 of file xml.c.

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, initStringInfo(), map_sql_identifier_to_xml_name(), and result.

Referenced by map_sql_catalog_to_xmlschema_types(), map_sql_schema_to_xmlschema_types(), map_sql_table_to_xmlschema(), and map_sql_type_to_xml_name().

3013 {
3015 
3016  initStringInfo(&result);
3017 
3018  if (a)
3019  appendStringInfoString(&result,
3020  map_sql_identifier_to_xml_name(a, true, true));
3021  if (b)
3022  appendStringInfo(&result, ".%s",
3023  map_sql_identifier_to_xml_name(b, true, true));
3024  if (c)
3025  appendStringInfo(&result, ".%s",
3026  map_sql_identifier_to_xml_name(c, true, true));
3027  if (d)
3028  appendStringInfo(&result, ".%s",
3029  map_sql_identifier_to_xml_name(d, true, true));
3030 
3031  return result.data;
3032 }
return result
Definition: formatting.c:1633
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * c
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static const char * map_sql_catalog_to_xmlschema_types ( List nspid_list,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3219 of file xml.c.

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, dbname, get_database_name(), get_namespace_name(), initStringInfo(), lfirst_oid, map_multipart_sql_identifier_to_xml_name(), map_sql_identifier_to_xml_name(), MyDatabaseId, NULL, and result.

Referenced by database_to_xmlschema_internal().

3221 {
3222  char *dbname;
3223  char *xmlcn;
3224  char *catalogtypename;
3226  ListCell *cell;
3227 
3228  dbname = get_database_name(MyDatabaseId);
3229 
3230  initStringInfo(&result);
3231 
3232  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3233 
3234  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3235  dbname,
3236  NULL,
3237  NULL);
3238 
3239  appendStringInfo(&result,
3240  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3241  appendStringInfoString(&result,
3242  " <xsd:all>\n");
3243 
3244  foreach(cell, nspid_list)
3245  {
3246  Oid nspid = lfirst_oid(cell);
3247  char *nspname = get_namespace_name(nspid);
3248  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3249  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3250  dbname,
3251  nspname,
3252  NULL);
3253 
3254  appendStringInfo(&result,
3255  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3256  xmlsn, schematypename);
3257  }
3258 
3259  appendStringInfoString(&result,
3260  " </xsd:all>\n");
3261  appendStringInfoString(&result,
3262  "</xsd:complexType>\n\n");
3263 
3264  appendStringInfo(&result,
3265  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3266  xmlcn, catalogtypename);
3267 
3268  return result.data;
3269 }
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
static char * map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d)
Definition: xml.c:3012
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
Oid MyDatabaseId
Definition: globals.c:77
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
#define lfirst_oid(lc)
Definition: pg_list.h:108
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
static const char * map_sql_schema_to_xmlschema_types ( Oid  nspid,
List relid_list,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3146 of file xml.c.

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, dbname, get_database_name(), get_namespace_name(), get_rel_name(), initStringInfo(), lfirst_oid, map_multipart_sql_identifier_to_xml_name(), map_sql_identifier_to_xml_name(), MyDatabaseId, NULL, and result.

Referenced by schema_to_xmlschema_internal().

3148 {
3149  char *dbname;
3150  char *nspname;
3151  char *xmlsn;
3152  char *schematypename;
3154  ListCell *cell;
3155 
3156  dbname = get_database_name(MyDatabaseId);
3157  nspname = get_namespace_name(nspid);
3158 
3159  initStringInfo(&result);
3160 
3161  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3162 
3163  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3164  dbname,
3165  nspname,
3166  NULL);
3167 
3168  appendStringInfo(&result,
3169  "<xsd:complexType name=\"%s\">\n", schematypename);
3170  if (!tableforest)
3171  appendStringInfoString(&result,
3172  " <xsd:all>\n");
3173  else
3174  appendStringInfoString(&result,
3175  " <xsd:sequence>\n");
3176 
3177  foreach(cell, relid_list)
3178  {
3179  Oid relid = lfirst_oid(cell);
3180  char *relname = get_rel_name(relid);
3181  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3182  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3183  dbname,
3184  nspname,
3185  relname);
3186 
3187  if (!tableforest)
3188  appendStringInfo(&result,
3189  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3190  xmltn, tabletypename);
3191  else
3192  appendStringInfo(&result,
3193  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3194  xmltn, tabletypename);
3195  }
3196 
3197  if (!tableforest)
3198  appendStringInfoString(&result,
3199  " </xsd:all>\n");
3200  else
3201  appendStringInfoString(&result,
3202  " </xsd:sequence>\n");
3203  appendStringInfoString(&result,
3204  "</xsd:complexType>\n\n");
3205 
3206  appendStringInfo(&result,
3207  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3208  xmlsn, schematypename);
3209 
3210  return result.data;
3211 }
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
static char * map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d)
Definition: xml.c:3012
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
Oid MyDatabaseId
Definition: globals.c:77
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
#define lfirst_oid(lc)
Definition: pg_list.h:108
static const char * map_sql_table_to_xmlschema ( TupleDesc  tupdesc,
Oid  relid,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3043 of file xml.c.

References appendStringInfo(), appendStringInfoString(), tupleDesc::attrs, StringInfoData::data, elog, ERROR, get_database_name(), get_namespace_name(), GETSTRUCT, HeapTupleIsValid, i, initStringInfo(), list_make1, map_multipart_sql_identifier_to_xml_name(), map_sql_identifier_to_xml_name(), map_sql_type_to_xml_name(), map_sql_typecoll_to_xmlschema_types(), MyDatabaseId, NameStr, tupleDesc::natts, ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), RELOID, result, SearchSysCache1, xsd_schema_element_end(), and xsd_schema_element_start().

Referenced by cursor_to_xmlschema(), query_to_xml_and_xmlschema(), query_to_xmlschema(), table_to_xml_and_xmlschema(), and table_to_xmlschema().

3045 {
3046  int i;
3047  char *xmltn;
3048  char *tabletypename;
3049  char *rowtypename;
3051 
3052  initStringInfo(&result);
3053 
3054  if (OidIsValid(relid))
3055  {
3056  HeapTuple tuple;
3057  Form_pg_class reltuple;
3058 
3059  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3060  if (!HeapTupleIsValid(tuple))
3061  elog(ERROR, "cache lookup failed for relation %u", relid);
3062  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3063 
3064  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3065  true, false);
3066 
3067  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3069  get_namespace_name(reltuple->relnamespace),
3070  NameStr(reltuple->relname));
3071 
3072  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3074  get_namespace_name(reltuple->relnamespace),
3075  NameStr(reltuple->relname));
3076 
3077  ReleaseSysCache(tuple);
3078  }
3079  else
3080  {
3081  if (tableforest)
3082  xmltn = "row";
3083  else
3084  xmltn = "table";
3085 
3086  tabletypename = "TableType";
3087  rowtypename = "RowType";
3088  }
3089 
3090  xsd_schema_element_start(&result, targetns);
3091 
3092  appendStringInfoString(&result,
3094 
3095  appendStringInfo(&result,
3096  "<xsd:complexType name=\"%s\">\n"
3097  " <xsd:sequence>\n",
3098  rowtypename);
3099 
3100  for (i = 0; i < tupdesc->natts; i++)
3101  {
3102  if (tupdesc->attrs[i]->attisdropped)
3103  continue;
3104  appendStringInfo(&result,
3105  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3106  map_sql_identifier_to_xml_name(NameStr(tupdesc->attrs[i]->attname),
3107  true, false),
3108  map_sql_type_to_xml_name(tupdesc->attrs[i]->atttypid, -1),
3109  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3110  }
3111 
3112  appendStringInfoString(&result,
3113  " </xsd:sequence>\n"
3114  "</xsd:complexType>\n\n");
3115 
3116  if (!tableforest)
3117  {
3118  appendStringInfo(&result,
3119  "<xsd:complexType name=\"%s\">\n"
3120  " <xsd:sequence>\n"
3121  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3122  " </xsd:sequence>\n"
3123  "</xsd:complexType>\n\n",
3124  tabletypename, rowtypename);
3125 
3126  appendStringInfo(&result,
3127  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3128  xmltn, tabletypename);
3129  }
3130  else
3131  appendStringInfo(&result,
3132  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3133  xmltn, rowtypename);
3134 
3135  xsd_schema_element_end(&result);
3136 
3137  return result.data;
3138 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2773
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Form_pg_attribute * attrs
Definition: tupdesc.h:74
return result
Definition: formatting.c:1633
static char * map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d)
Definition: xml.c:3012
#define OidIsValid(objectId)
Definition: c.h:538
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define list_make1(x1)
Definition: pg_list.h:139
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3381
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3276
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2790
Oid MyDatabaseId
Definition: globals.c:77
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int i
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
static const char * map_sql_type_to_xml_name ( Oid  typeoid,
int  typmod 
)
static

Definition at line 3276 of file xml.c.

References appendStringInfo(), appendStringInfoString(), BOOLOID, BPCHAROID, StringInfoData::data, DATEOID, elog, ERROR, FLOAT4OID, FLOAT8OID, get_database_name(), get_namespace_name(), GETSTRUCT, HeapTupleIsValid, initStringInfo(), INT2OID, INT4OID, INT8OID, map_multipart_sql_identifier_to_xml_name(), MyDatabaseId, NameStr, NUMERICOID, ObjectIdGetDatum, ReleaseSysCache(), result, SearchSysCache1, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, TYPEOID, TYPTYPE_DOMAIN, VARCHAROID, VARHDRSZ, and XMLOID.

Referenced by map_sql_table_to_xmlschema(), and map_sql_type_to_xmlschema_type().

3277 {
3279 
3280  initStringInfo(&result);
3281 
3282  switch (typeoid)
3283  {
3284  case BPCHAROID:
3285  if (typmod == -1)
3286  appendStringInfoString(&result, "CHAR");
3287  else
3288  appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3289  break;
3290  case VARCHAROID:
3291  if (typmod == -1)
3292  appendStringInfoString(&result, "VARCHAR");
3293  else
3294  appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3295  break;
3296  case NUMERICOID:
3297  if (typmod == -1)
3298  appendStringInfoString(&result, "NUMERIC");
3299  else
3300  appendStringInfo(&result, "NUMERIC_%d_%d",
3301  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3302  (typmod - VARHDRSZ) & 0xffff);
3303  break;
3304  case INT4OID:
3305  appendStringInfoString(&result, "INTEGER");
3306  break;
3307  case INT2OID:
3308  appendStringInfoString(&result, "SMALLINT");
3309  break;
3310  case INT8OID:
3311  appendStringInfoString(&result, "BIGINT");
3312  break;
3313  case FLOAT4OID:
3314  appendStringInfoString(&result, "REAL");
3315  break;
3316  case FLOAT8OID:
3317  appendStringInfoString(&result, "DOUBLE");
3318  break;
3319  case BOOLOID:
3320  appendStringInfoString(&result, "BOOLEAN");
3321  break;
3322  case TIMEOID:
3323  if (typmod == -1)
3324  appendStringInfoString(&result, "TIME");
3325  else
3326  appendStringInfo(&result, "TIME_%d", typmod);
3327  break;
3328  case TIMETZOID:
3329  if (typmod == -1)
3330  appendStringInfoString(&result, "TIME_WTZ");
3331  else
3332  appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3333  break;
3334  case TIMESTAMPOID:
3335  if (typmod == -1)
3336  appendStringInfoString(&result, "TIMESTAMP");
3337  else
3338  appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3339  break;
3340  case TIMESTAMPTZOID:
3341  if (typmod == -1)
3342  appendStringInfoString(&result, "TIMESTAMP_WTZ");
3343  else
3344  appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3345  break;
3346  case DATEOID:
3347  appendStringInfoString(&result, "DATE");
3348  break;
3349  case XMLOID:
3350  appendStringInfoString(&result, "XML");
3351  break;
3352  default:
3353  {
3354  HeapTuple tuple;
3355  Form_pg_type typtuple;
3356 
3357  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3358  if (!HeapTupleIsValid(tuple))
3359  elog(ERROR, "cache lookup failed for type %u", typeoid);
3360  typtuple = (Form_pg_type) GETSTRUCT(tuple);
3361 
3362  appendStringInfoString(&result,
3363  map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3365  get_namespace_name(typtuple->typnamespace),
3366  NameStr(typtuple->typname)));
3367 
3368  ReleaseSysCache(tuple);
3369  }
3370  }
3371 
3372  return result.data;
3373 }
#define TIMESTAMPTZOID
Definition: pg_type.h:525
#define TIMEOID
Definition: pg_type.h:514
#define TYPTYPE_DOMAIN
Definition: pg_type.h:722
#define BPCHAROID
Definition: pg_type.h:504
#define DATEOID
Definition: pg_type.h:511
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define NUMERICOID
Definition: pg_type.h:554
#define VARHDRSZ
Definition: c.h:445
#define INT4OID
Definition: pg_type.h:316
return result
Definition: formatting.c:1633
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
static char * map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d)
Definition: xml.c:3012
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define TIMESTAMPOID
Definition: pg_type.h:519
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
#define INT2OID
Definition: pg_type.h:308
#define XMLOID
Definition: pg_type.h:359
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define VARCHAROID
Definition: pg_type.h:507
#define FLOAT4OID
Definition: pg_type.h:416
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Oid MyDatabaseId
Definition: globals.c:77
#define INT8OID
Definition: pg_type.h:304
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define TIMETZOID
Definition: pg_type.h:536
#define FLOAT8OID
Definition: pg_type.h:419
#define BOOLOID
Definition: pg_type.h:288
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
static const char * map_sql_type_to_xmlschema_type ( Oid  typeoid,
int  typmod 
)
static

Definition at line 3435 of file xml.c.

References appendStringInfo(), appendStringInfoString(), BOOLOID, BPCHAROID, BYTEAOID, StringInfoData::data, DATEOID, FLOAT4OID, FLOAT8OID, get_typtype(), getBaseTypeAndTypmod(), initStringInfo(), INT2OID, INT4OID, INT64_FORMAT, INT8OID, map_sql_type_to_xml_name(), NUMERICOID, result, TEXTOID, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, TYPTYPE_DOMAIN, VARCHAROID, VARHDRSZ, xmlbinary, XMLBINARY_BASE64, and XMLOID.

Referenced by map_sql_typecoll_to_xmlschema_types().

3436 {
3438  const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3439 
3440  initStringInfo(&result);
3441 
3442  if (typeoid == XMLOID)
3443  {
3444  appendStringInfoString(&result,
3445  "<xsd:complexType mixed=\"true\">\n"
3446  " <xsd:sequence>\n"
3447  " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3448  " </xsd:sequence>\n"
3449  "</xsd:complexType>\n");
3450  }
3451  else
3452  {
3453  appendStringInfo(&result,
3454  "<xsd:simpleType name=\"%s\">\n", typename);
3455 
3456  switch (typeoid)
3457  {
3458  case BPCHAROID:
3459  case VARCHAROID:
3460  case TEXTOID:
3461  appendStringInfo(&result,
3462  " <xsd:restriction base=\"xsd:string\">\n");
3463  if (typmod != -1)
3464  appendStringInfo(&result,
3465  " <xsd:maxLength value=\"%d\"/>\n",
3466  typmod - VARHDRSZ);
3467  appendStringInfoString(&result, " </xsd:restriction>\n");
3468  break;
3469 
3470  case BYTEAOID:
3471  appendStringInfo(&result,
3472  " <xsd:restriction base=\"xsd:%s\">\n"
3473  " </xsd:restriction>\n",
3474  xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3475  break;
3476 
3477  case NUMERICOID:
3478  if (typmod != -1)
3479  appendStringInfo(&result,
3480  " <xsd:restriction base=\"xsd:decimal\">\n"
3481  " <xsd:totalDigits value=\"%d\"/>\n"
3482  " <xsd:fractionDigits value=\"%d\"/>\n"
3483  " </xsd:restriction>\n",
3484  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3485  (typmod - VARHDRSZ) & 0xffff);
3486  break;
3487 
3488  case INT2OID:
3489  appendStringInfo(&result,
3490  " <xsd:restriction base=\"xsd:short\">\n"
3491  " <xsd:maxInclusive value=\"%d\"/>\n"
3492  " <xsd:minInclusive value=\"%d\"/>\n"
3493  " </xsd:restriction>\n",
3494  SHRT_MAX, SHRT_MIN);
3495  break;
3496 
3497  case INT4OID:
3498  appendStringInfo(&result,
3499  " <xsd:restriction base=\"xsd:int\">\n"
3500  " <xsd:maxInclusive value=\"%d\"/>\n"
3501  " <xsd:minInclusive value=\"%d\"/>\n"
3502  " </xsd:restriction>\n",
3503  INT_MAX, INT_MIN);
3504  break;
3505 
3506  case INT8OID:
3507  appendStringInfo(&result,
3508  " <xsd:restriction base=\"xsd:long\">\n"
3509  " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3510  " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3511  " </xsd:restriction>\n",
3512  (((uint64) 1) << (sizeof(int64) * 8 - 1)) - 1,
3513  (((uint64) 1) << (sizeof(int64) * 8 - 1)));
3514  break;
3515 
3516  case FLOAT4OID:
3517  appendStringInfoString(&result,
3518  " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3519  break;
3520 
3521  case FLOAT8OID:
3522  appendStringInfoString(&result,
3523  " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3524  break;
3525 
3526  case BOOLOID:
3527  appendStringInfoString(&result,
3528  " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
3529  break;
3530 
3531  case TIMEOID:
3532  case TIMETZOID:
3533  {
3534  const char *tz = (typeoid == TIMETZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3535 
3536  if (typmod == -1)
3537  appendStringInfo(&result,
3538  " <xsd:restriction base=\"xsd:time\">\n"
3539  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3540  " </xsd:restriction>\n", tz);
3541  else if (typmod == 0)
3542  appendStringInfo(&result,
3543  " <xsd:restriction base=\"xsd:time\">\n"
3544  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3545  " </xsd:restriction>\n", tz);
3546  else
3547  appendStringInfo(&result,
3548  " <xsd:restriction base=\"xsd:time\">\n"
3549  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3550  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3551  break;
3552  }
3553 
3554  case TIMESTAMPOID:
3555  case TIMESTAMPTZOID:
3556  {
3557  const char *tz = (typeoid == TIMESTAMPTZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3558 
3559  if (typmod == -1)
3560  appendStringInfo(&result,
3561  " <xsd:restriction base=\"xsd:dateTime\">\n"
3562  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3563  " </xsd:restriction>\n", tz);
3564  else if (typmod == 0)
3565  appendStringInfo(&result,
3566  " <xsd:restriction base=\"xsd:dateTime\">\n"
3567  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3568  " </xsd:restriction>\n", tz);
3569  else
3570  appendStringInfo(&result,
3571  " <xsd:restriction base=\"xsd:dateTime\">\n"
3572  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3573  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3574  break;
3575  }
3576 
3577  case DATEOID:
3578  appendStringInfoString(&result,
3579  " <xsd:restriction base=\"xsd:date\">\n"
3580  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
3581  " </xsd:restriction>\n");
3582  break;
3583 
3584  default:
3585  if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
3586  {
3587  Oid base_typeoid;
3588  int32 base_typmod = -1;
3589 
3590  base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
3591 
3592  appendStringInfo(&result,
3593  " <xsd:restriction base=\"%s\"/>\n",
3594  map_sql_type_to_xml_name(base_typeoid, base_typmod));
3595  }
3596  break;
3597  }
3598  appendStringInfoString(&result, "</xsd:simpleType>\n");
3599  }
3600 
3601  return result.data;
3602 }
#define TIMESTAMPTZOID
Definition: pg_type.h:525
#define TIMEOID
Definition: pg_type.h:514
#define TYPTYPE_DOMAIN
Definition: pg_type.h:722
#define BPCHAROID
Definition: pg_type.h:504
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2288
#define DATEOID
Definition: pg_type.h:511
#define TEXTOID
Definition: pg_type.h:324
#define NUMERICOID
Definition: pg_type.h:554
#define VARHDRSZ
Definition: c.h:445
#define INT4OID
Definition: pg_type.h:316
char get_typtype(Oid typid)
Definition: lsyscache.c:2379
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:256
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define TIMESTAMPOID
Definition: pg_type.h:519
#define INT2OID
Definition: pg_type.h:308
#define XMLOID
Definition: pg_type.h:359
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3276
#define VARCHAROID
Definition: pg_type.h:507
#define FLOAT4OID
Definition: pg_type.h:416
#define INT8OID
Definition: pg_type.h:304
#define TIMETZOID
Definition: pg_type.h:536
#define FLOAT8OID
Definition: pg_type.h:419
#define BOOLOID
Definition: pg_type.h:288
int xmlbinary
Definition: xml.c:96
#define INT64_FORMAT
Definition: c.h:315
#define BYTEAOID
Definition: pg_type.h:292
static const char * map_sql_typecoll_to_xmlschema_types ( List tupdesc_list)
static

Definition at line 3381 of file xml.c.

References appendStringInfo(), tupleDesc::attrs, StringInfoData::data, getBaseType(), i, initStringInfo(), lfirst, lfirst_oid, list_append_unique_oid(), map_sql_type_to_xmlschema_type(), tupleDesc::natts, NIL, and result.

Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().

3382 {
3383  List *uniquetypes = NIL;
3384  int i;
3386  ListCell *cell0;
3387 
3388  /* extract all column types used in the set of TupleDescs */
3389  foreach(cell0, tupdesc_list)
3390  {
3391  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3392 
3393  for (i = 0; i < tupdesc->natts; i++)
3394  {
3395  if (tupdesc->attrs[i]->attisdropped)
3396  continue;
3397  uniquetypes = list_append_unique_oid(uniquetypes,
3398  tupdesc->attrs[i]->atttypid);
3399  }
3400  }
3401 
3402  /* add base types of domains */
3403  foreach(cell0, uniquetypes)
3404  {
3405  Oid typid = lfirst_oid(cell0);
3406  Oid basetypid = getBaseType(typid);
3407 
3408  if (basetypid != typid)
3409  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3410  }
3411 
3412  /* Convert to textual form */
3413  initStringInfo(&result);
3414 
3415  foreach(cell0, uniquetypes)
3416  {
3417  appendStringInfo(&result, "%s\n",
3419  -1));
3420  }
3421 
3422  return result.data;
3423 }
#define NIL
Definition: pg_list.h:69
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:999
Form_pg_attribute * attrs
Definition: tupdesc.h:74
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
struct tupleDesc * TupleDesc
#define lfirst(lc)
Definition: pg_list.h:106
int i
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2271
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3435
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
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
static List* query_to_oid_list ( const char *  query)
static

Definition at line 2321 of file xml.c.

References DatumGetObjectId, i, lappend_oid(), sort-test::list, NIL, SPI_execute(), SPI_getbinval(), SPI_processed, SPI_tuptable, SPITupleTable::tupdesc, and SPITupleTable::vals.

Referenced by database_get_xml_visible_schemas(), database_get_xml_visible_tables(), and schema_get_xml_visible_tables().

2322 {
2323  uint64 i;
2324  List *list = NIL;
2325 
2326  SPI_execute(query, true, 0);
2327 
2328  for (i = 0; i < SPI_processed; i++)
2329  {
2330  Datum oid;
2331  bool isnull;
2332 
2333  oid = SPI_getbinval(SPI_tuptable->vals[i],
2335  1,
2336  &isnull);
2337  if (!isnull)
2338  list = lappend_oid(list, DatumGetObjectId(oid));
2339  }
2340 
2341  return list;
2342 }
#define NIL
Definition: pg_list.h:69
#define DatumGetObjectId(X)
Definition: postgres.h:506
SPITupleTable * SPI_tuptable
Definition: spi.c:41
HeapTuple * vals
Definition: spi.h:28
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
uint64 SPI_processed
Definition: spi.c:39
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:836
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc
Definition: spi.h:27
tuple list
Definition: sort-test.py:11
int i
Definition: pg_list.h:45
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:304
Datum query_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2430 of file xml.c.

References NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, query_to_xml_internal(), stringinfo_to_xmltype(), and text_to_cstring().

2431 {
2432  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2433  bool nulls = PG_GETARG_BOOL(1);
2434  bool tableforest = PG_GETARG_BOOL(2);
2435  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2436 
2438  NULL, nulls, tableforest,
2439  targetns, true)));
2440 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2532
#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
Datum query_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2672 of file xml.c.

References _SPI_strdup(), elog, ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, query_to_xml_internal(), SPI_connect(), SPI_cursor_close(), SPI_cursor_open(), SPI_finish(), SPI_prepare(), stringinfo_to_xmltype(), text_to_cstring(), and PortalData::tupDesc.

2673 {
2674  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2675  bool nulls = PG_GETARG_BOOL(1);
2676  bool tableforest = PG_GETARG_BOOL(2);
2677  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2678 
2679  const char *xmlschema;
2680  SPIPlanPtr plan;
2681  Portal portal;
2682 
2683  SPI_connect();
2684 
2685  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2686  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2687 
2688  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2689  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2690 
2691  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2692  InvalidOid, nulls, tableforest, targetns));
2693  SPI_cursor_close(portal);
2694  SPI_finish();
2695 
2697  xmlschema, nulls, tableforest,
2698  targetns, true)));
2699 }
int SPI_connect(void)
Definition: spi.c:84
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:482
int SPI_finish(void)
Definition: spi.c:148
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1029
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2264
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3043
TupleDesc tupDesc
Definition: portal.h:155
#define InvalidOid
Definition: postgres_ext.h:36
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2532
#define NULL
Definition: c.h:229
void SPI_cursor_close(Portal portal)
Definition: spi.c:1403
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
#define elog
Definition: elog.h:219
static StringInfo query_to_xml_internal ( const char *  query,
char *  tablename,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2532 of file xml.c.

References appendStringInfo(), appendStringInfoChar(), ereport, errcode(), errmsg(), ERROR, i, makeStringInfo(), map_sql_identifier_to_xml_name(), result, SPI_connect(), SPI_execute(), SPI_finish(), SPI_OK_SELECT, SPI_processed, SPI_sql_row_to_xmlelement(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by query_to_xml(), query_to_xml_and_xmlschema(), and table_to_xml_internal().

2535 {
2537  char *xmltn;
2538  uint64 i;
2539 
2540  if (tablename)
2541  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2542  else
2543  xmltn = "table";
2544 
2545  result = makeStringInfo();
2546 
2547  SPI_connect();
2548  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2549  ereport(ERROR,
2550  (errcode(ERRCODE_DATA_EXCEPTION),
2551  errmsg("invalid query")));
2552 
2553  if (!tableforest)
2554  {
2555  xmldata_root_element_start(result, xmltn, xmlschema,
2556  targetns, top_level);
2557  appendStringInfoChar(result, '\n');
2558  }
2559 
2560  if (xmlschema)
2561  appendStringInfo(result, "%s\n\n", xmlschema);
2562 
2563  for (i = 0; i < SPI_processed; i++)
2564  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2565  tableforest, targetns, top_level);
2566 
2567  if (!tableforest)
2568  xmldata_root_element_end(result, xmltn);
2569 
2570  SPI_finish();
2571 
2572  return result;
2573 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2498
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
uint64 SPI_processed
Definition: spi.c:39
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
#define SPI_OK_SELECT
Definition: spi.h:54
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2525
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
static void SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3610
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:304
Datum query_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2596 of file xml.c.

References _SPI_strdup(), cstring_to_xmltype(), elog, ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, result, SPI_connect(), SPI_cursor_close(), SPI_cursor_open(), SPI_finish(), SPI_prepare(), text_to_cstring(), and PortalData::tupDesc.

2597 {
2598  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2599  bool nulls = PG_GETARG_BOOL(1);
2600  bool tableforest = PG_GETARG_BOOL(2);
2601  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2602  const char *result;
2603  SPIPlanPtr plan;
2604  Portal portal;
2605 
2606  SPI_connect();
2607 
2608  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2609  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2610 
2611  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2612  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2613 
2615  InvalidOid, nulls,
2616  tableforest, targetns));
2617  SPI_cursor_close(portal);
2618  SPI_finish();
2619 
2621 }
int SPI_connect(void)
Definition: spi.c:84
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:482
int SPI_finish(void)
Definition: spi.c:148
return result
Definition: formatting.c:1633
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1029
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2264
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3043
TupleDesc tupDesc
Definition: portal.h:155
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:452
#define NULL
Definition: c.h:229
void SPI_cursor_close(Portal portal)
Definition: spi.c:1403
char * text_to_cstring(const text *t)
Definition: varlena.c:182
#define elog
Definition: elog.h:219
static List* schema_get_xml_visible_tables ( Oid  nspid)
static

Definition at line 2346 of file xml.c.

References appendStringInfo(), CppAsString2, StringInfoData::data, initStringInfo(), query_to_oid_list(), RELKIND_MATVIEW, RELKIND_RELATION, and RELKIND_VIEW.

Referenced by schema_to_xml_internal(), and schema_to_xmlschema_internal().

2347 {
2348  StringInfoData query;
2349 
2350  initStringInfo(&query);
2351  appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2352  " WHERE relnamespace = %u AND relkind IN ("
2356  " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2357  " ORDER BY relname;", nspid);
2358 
2359  return query_to_oid_list(query.data);
2360 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2321
#define RELKIND_MATVIEW
Definition: pg_class.h:165
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define CppAsString2(x)
Definition: c.h:162
#define RELKIND_VIEW
Definition: pg_class.h:164
#define RELKIND_RELATION
Definition: pg_class.h:160
Datum schema_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2751 of file xml.c.

References LookupExplicitNamespace(), NameStr, NULL, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xml_internal(), stringinfo_to_xmltype(), and text_to_cstring().

2752 {
2753  Name name = PG_GETARG_NAME(0);
2754  bool nulls = PG_GETARG_BOOL(1);
2755  bool tableforest = PG_GETARG_BOOL(2);
2756  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2757 
2758  char *schemaname;
2759  Oid nspid;
2760 
2761  schemaname = NameStr(*name);
2762  nspid = LookupExplicitNamespace(schemaname, false);
2763 
2765  nulls, tableforest, targetns, true)));
2766 }
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2708
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Definition: c.h:493
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define NULL
Definition: c.h:229
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
#define NameStr(name)
Definition: c.h:499
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243
Datum schema_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2855 of file xml.c.

References StringInfoData::data, LookupExplicitNamespace(), NameStr, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xml_internal(), schema_to_xmlschema_internal(), stringinfo_to_xmltype(), and text_to_cstring().

2856 {
2857  Name name = PG_GETARG_NAME(0);
2858  bool nulls = PG_GETARG_BOOL(1);
2859  bool tableforest = PG_GETARG_BOOL(2);
2860  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2861  char *schemaname;
2862  Oid nspid;
2863  StringInfo xmlschema;
2864 
2865  schemaname = NameStr(*name);
2866  nspid = LookupExplicitNamespace(schemaname, false);
2867 
2868  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
2869  tableforest, targetns);
2870 
2872  xmlschema->data, nulls,
2873  tableforest, targetns, true)));
2874 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2797
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2708
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Definition: c.h:493
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
#define NameStr(name)
Definition: c.h:499
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243
static StringInfo schema_to_xml_internal ( Oid  nspid,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2708 of file xml.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, get_namespace_name(), lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), NULL, result, schema_get_xml_visible_tables(), SPI_connect(), SPI_finish(), table_to_xml_internal(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by database_to_xml_internal(), schema_to_xml(), and schema_to_xml_and_xmlschema().

2710 {
2712  char *xmlsn;
2713  List *relid_list;
2714  ListCell *cell;
2715 
2717  true, false);
2718  result = makeStringInfo();
2719 
2720  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
2721  appendStringInfoChar(result, '\n');
2722 
2723  if (xmlschema)
2724  appendStringInfo(result, "%s\n\n", xmlschema);
2725 
2726  SPI_connect();
2727 
2728  relid_list = schema_get_xml_visible_tables(nspid);
2729 
2730  foreach(cell, relid_list)
2731  {
2732  Oid relid = lfirst_oid(cell);
2733  StringInfo subres;
2734 
2735  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
2736  targetns, false);
2737 
2738  appendStringInfoString(result, subres->data);
2739  appendStringInfoChar(result, '\n');
2740  }
2741 
2742  SPI_finish();
2743 
2744  xmldata_root_element_end(result, xmlsn);
2745 
2746  return result;
2747 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2498
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2346
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
#define NULL
Definition: c.h:229
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2399
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2525
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2842 of file xml.c.

References NameStr, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xmlschema_internal(), stringinfo_to_xmltype(), and text_to_cstring().

2843 {
2844  Name name = PG_GETARG_NAME(0);
2845  bool nulls = PG_GETARG_BOOL(1);
2846  bool tableforest = PG_GETARG_BOOL(2);
2847  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2848 
2850  nulls, tableforest, targetns)));
2851 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2797
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Definition: c.h:493
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
#define NameStr(name)
Definition: c.h:499
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243
static StringInfo schema_to_xmlschema_internal ( const char *  schemaname,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 2797 of file xml.c.

References AccessShareLock, appendStringInfoString(), CreateTupleDescCopy(), heap_close, heap_open(), lappend(), lfirst_oid, LookupExplicitNamespace(), makeStringInfo(), map_sql_schema_to_xmlschema_types(), map_sql_typecoll_to_xmlschema_types(), NIL, NoLock, RelationData::rd_att, result, schema_get_xml_visible_tables(), SPI_connect(), SPI_finish(), xsd_schema_element_end(), and xsd_schema_element_start().

Referenced by schema_to_xml_and_xmlschema(), and schema_to_xmlschema().

2799 {
2800  Oid nspid;
2801  List *relid_list;
2802  List *tupdesc_list;
2803  ListCell *cell;
2805 
2806  result = makeStringInfo();
2807 
2808  nspid = LookupExplicitNamespace(schemaname, false);
2809 
2810  xsd_schema_element_start(result, targetns);
2811 
2812  SPI_connect();
2813 
2814  relid_list = schema_get_xml_visible_tables(nspid);
2815 
2816  tupdesc_list = NIL;
2817  foreach(cell, relid_list)
2818  {
2819  Relation rel;
2820 
2821  rel = heap_open(lfirst_oid(cell), AccessShareLock);
2822  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2823  heap_close(rel, NoLock);
2824  }
2825 
2826  appendStringInfoString(result,
2827  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2828 
2829  appendStringInfoString(result,
2830  map_sql_schema_to_xmlschema_types(nspid, relid_list,
2831  nulls, tableforest, targetns));
2832 
2833  xsd_schema_element_end(result);
2834 
2835  SPI_finish();
2836 
2837  return result;
2838 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2773
#define NIL
Definition: pg_list.h:69
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2346
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:148
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1633
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:128
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3381
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2790
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
TupleDesc rd_att
Definition: rel.h:115
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3146
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
static void SPI_sql_row_to_xmlelement ( uint64  rownum,
StringInfo  result,
char *  tablename,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 3610 of file xml.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), i, map_sql_identifier_to_xml_name(), map_sql_value_to_xml_value(), tupleDesc::natts, NULL, SPI_fname(), SPI_getbinval(), SPI_gettypeid(), SPI_tuptable, SPITupleTable::tupdesc, SPITupleTable::vals, xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by cursor_to_xml(), and query_to_xml_internal().

3613 {
3614  int i;
3615  char *xmltn;
3616 
3617  if (tablename)
3618  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3619  else
3620  {
3621  if (tableforest)
3622  xmltn = "row";
3623  else
3624  xmltn = "table";
3625  }
3626 
3627  if (tableforest)
3628  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
3629  else
3630  appendStringInfoString(result, "<row>\n");
3631 
3632  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
3633  {
3634  char *colname;
3635  Datum colval;
3636  bool isnull;
3637 
3639  true, false);
3640  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
3642  i,
3643  &isnull);
3644  if (isnull)
3645  {
3646  if (nulls)
3647  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
3648  }
3649  else
3650  appendStringInfo(result, " <%s>%s</%s>\n",
3651  colname,
3653  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
3654  colname);
3655  }
3656 
3657  if (tableforest)
3658  {
3659  xmldata_root_element_end(result, xmltn);
3660  appendStringInfoChar(result, '\n');
3661  }
3662  else
3663  appendStringInfoString(result, "</row>\n\n");
3664 }
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:892
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2498
SPITupleTable * SPI_tuptable
Definition: spi.c:41
HeapTuple * vals
Definition: spi.h:28
int natts
Definition: tupdesc.h:73
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:782
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1897
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:836
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc
Definition: spi.h:27
#define NULL
Definition: c.h:229
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2525
int i
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2013
Datum table_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2416 of file xml.c.

References NULL, PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), table_to_xml_internal(), and text_to_cstring().

2417 {
2418  Oid relid = PG_GETARG_OID(0);
2419  bool nulls = PG_GETARG_BOOL(1);
2420  bool tableforest = PG_GETARG_BOOL(2);
2421  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2422 
2424  nulls, tableforest,
2425  targetns, true)));
2426 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define NULL
Definition: c.h:229
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2399
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
Datum table_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2651 of file xml.c.

References AccessShareLock, heap_close, heap_open(), map_sql_table_to_xmlschema(), NoLock, PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, RelationData::rd_att, stringinfo_to_xmltype(), table_to_xml_internal(), and text_to_cstring().

2652 {
2653  Oid relid = PG_GETARG_OID(0);
2654  bool nulls = PG_GETARG_BOOL(1);
2655  bool tableforest = PG_GETARG_BOOL(2);
2656  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2657  Relation rel;
2658  const char *xmlschema;
2659 
2660  rel = heap_open(relid, AccessShareLock);
2661  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2662  tableforest, targetns);
2663  heap_close(rel, NoLock);
2664 
2666  xmlschema, nulls, tableforest,
2667  targetns, true)));
2668 }
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define NoLock
Definition: lockdefs.h:34
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3043
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
TupleDesc rd_att
Definition: rel.h:115
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2399
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
static StringInfo table_to_xml_internal ( Oid  relid,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2399 of file xml.c.

References appendStringInfo(), StringInfoData::data, DatumGetCString, DirectFunctionCall1, get_rel_name(), initStringInfo(), ObjectIdGetDatum, query_to_xml_internal(), and regclassout().

Referenced by schema_to_xml_internal(), table_to_xml(), and table_to_xml_and_xmlschema().

2402 {
2403  StringInfoData query;
2404 
2405  initStringInfo(&query);
2406  appendStringInfo(&query, "SELECT * FROM %s",
2408  ObjectIdGetDatum(relid))));
2409  return query_to_xml_internal(query.data, get_rel_name(relid),
2410  xmlschema, nulls, tableforest,
2411  targetns, top_level);
2412 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define DatumGetCString(X)
Definition: postgres.h:572
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2532
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:972
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
Datum table_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2577 of file xml.c.

References AccessShareLock, cstring_to_xmltype(), heap_close, heap_open(), map_sql_table_to_xmlschema(), NoLock, PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, RelationData::rd_att, result, and text_to_cstring().

2578 {
2579  Oid relid = PG_GETARG_OID(0);
2580  bool nulls = PG_GETARG_BOOL(1);
2581  bool tableforest = PG_GETARG_BOOL(2);
2582  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2583  const char *result;
2584  Relation rel;
2585 
2586  rel = heap_open(relid, AccessShareLock);
2587  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2588  tableforest, targetns);
2589  heap_close(rel, NoLock);
2590 
2592 }
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1633
#define heap_close(r, l)
Definition: heapam.h:97
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define NoLock
Definition: lockdefs.h:34
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3043
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
TupleDesc rd_att
Definition: rel.h:115
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:452
char * text_to_cstring(const text *t)
Definition: varlena.c:182
Datum texttoxml ( PG_FUNCTION_ARGS  )

Definition at line 594 of file xml.c.

References PG_GETARG_TEXT_PP, PG_RETURN_XML_P, xmloption, and xmlparse().

595 {
596  text *data = PG_GETARG_TEXT_PP(0);
597 
598  PG_RETURN_XML_P(xmlparse(data, xmloption, true));
599 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
int xmloption
Definition: xml.c:97
Definition: c.h:439
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:750
static char* unicode_to_sqlchar ( pg_wchar  c)
static

Definition at line 1953 of file xml.c.

References pg_any_to_server(), PG_UTF8, pstrdup(), result, and unicode_to_utf8().

Referenced by map_xml_name_to_sql_identifier().

1954 {
1955  char utf8string[8]; /* need room for trailing zero */
1956  char *result;
1957 
1958  memset(utf8string, 0, sizeof(utf8string));
1959  unicode_to_utf8(c, (unsigned char *) utf8string);
1960 
1961  result = pg_any_to_server(utf8string, strlen(utf8string), PG_UTF8);
1962  /* if pg_any_to_server didn't strdup, we must */
1963  if (result == utf8string)
1964  result = pstrdup(result);
1965  return result;
1966 }
unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
Definition: wchar.c:475
char * pstrdup(const char *in)
Definition: mcxt.c:1077
return result
Definition: formatting.c:1633
char * c
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:572
Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 256 of file xml.c.

References cstring_to_text(), GetDatabaseEncoding(), NO_XML_SUPPORT, PG_GETARG_CSTRING, PG_RETURN_XML_P, and xmloption.

257 {
258 #ifdef USE_LIBXML
259  char *s = PG_GETARG_CSTRING(0);
260  xmltype *vardata;
261  xmlDocPtr doc;
262 
263  vardata = (xmltype *) cstring_to_text(s);
264 
265  /*
266  * Parse the data to check if it is well-formed XML data. Assume that
267  * ERROR occurred if parsing failed.
268  */
269  doc = xml_parse(vardata, xmloption, true, GetDatabaseEncoding());
270  xmlFreeDoc(doc);
271 
272  PG_RETURN_XML_P(vardata);
273 #else
274  NO_XML_SUPPORT();
275  return 0;
276 #endif
277 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
text * cstring_to_text(const char *s)
Definition: varlena.c:149
int xmloption
Definition: xml.c:97
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
Definition: c.h:439
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
Datum xml_is_well_formed ( PG_FUNCTION_ARGS  )

Definition at line 4109 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and xmloption.

4110 {
4111 #ifdef USE_LIBXML
4112  text *data = PG_GETARG_TEXT_PP(0);
4113 
4114  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4115 #else
4116  NO_XML_SUPPORT();
4117  return 0;
4118 #endif /* not USE_LIBXML */
4119 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int xmloption
Definition: xml.c:97
Definition: c.h:439
Datum xml_is_well_formed_content ( PG_FUNCTION_ARGS  )

Definition at line 4135 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_CONTENT.

4136 {
4137 #ifdef USE_LIBXML
4138  text *data = PG_GETARG_TEXT_PP(0);
4139 
4140  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4141 #else
4142  NO_XML_SUPPORT();
4143  return 0;
4144 #endif /* not USE_LIBXML */
4145 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
Definition: c.h:439
Datum xml_is_well_formed_document ( PG_FUNCTION_ARGS  )

Definition at line 4122 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.

4123 {
4124 #ifdef USE_LIBXML
4125  text *data = PG_GETARG_TEXT_PP(0);
4126 
4127  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4128 #else
4129  NO_XML_SUPPORT();
4130  return 0;
4131 #endif /* not USE_LIBXML */
4132 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
Definition: c.h:439
Datum xml_out ( PG_FUNCTION_ARGS  )

Definition at line 334 of file xml.c.

References PG_GETARG_XML_P, PG_RETURN_CSTRING, and xml_out_internal().

335 {
336  xmltype *x = PG_GETARG_XML_P(0);
337 
338  /*
339  * xml_out removes the encoding property in all cases. This is because we
340  * cannot control from here whether the datum will be converted to a
341  * different client encoding, so we'd do more harm than good by including
342  * it.
343  */
345 }
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:291
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
Definition: c.h:439
static char* xml_out_internal ( xmltype x,
pg_enc  target_encoding 
)
static

Definition at line 291 of file xml.c.

References appendStringInfoString(), buf, StringInfoData::data, initStringInfo(), NULL, pfree(), text_to_cstring(), and WARNING.

Referenced by xml_out(), xml_send(), and XmlTableSetDocument().

292 {
293  char *str = text_to_cstring((text *) x);
294 
295 #ifdef USE_LIBXML
296  size_t len = strlen(str);
297  xmlChar *version;
298  int standalone;
299  int res_code;
300 
301  if ((res_code = parse_xml_decl((xmlChar *) str,
302  &len, &version, NULL, &standalone)) == 0)
303  {
305 
306  initStringInfo(&buf);
307 
308  if (!print_xml_decl(&buf, version, target_encoding, standalone))
309  {
310  /*
311  * If we are not going to produce an XML declaration, eat a single
312  * newline in the original string to prevent empty first lines in
313  * the output.
314  */
315  if (*(str + len) == '\n')
316  len += 1;
317  }
318  appendStringInfoString(&buf, str + len);
319 
320  pfree(str);
321 
322  return buf.data;
323  }
324 
325  xml_ereport_by_code(WARNING, ERRCODE_INTERNAL_ERROR,
326  "could not parse XML declaration in stored value",
327  res_code);
328 #endif
329  return str;
330 }
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 WARNING
Definition: elog.h:40
#define NULL
Definition: c.h:229
char * text_to_cstring(const text *t)
Definition: varlena.c:182
Definition: c.h:439
Datum xml_recv ( PG_FUNCTION_ARGS  )

Definition at line 349 of file xml.c.

References buf, cstring_to_text(), StringInfoData::cursor, encoding, StringInfoData::len, NO_XML_SUPPORT, NULL, palloc(), pfree(), pg_any_to_server(), PG_GETARG_POINTER, PG_RETURN_XML_P, PG_UTF8, pq_getmsgbytes(), result, SET_VARSIZE, VARDATA, VARHDRSZ, and xmloption.

350 {
351 #ifdef USE_LIBXML
353  xmltype *result;
354  char *str;
355  char *newstr;
356  int nbytes;
357  xmlDocPtr doc;
358  xmlChar *encodingStr = NULL;
359  int encoding;
360 
361  /*
362  * Read the data in raw format. We don't know yet what the encoding is, as
363  * that information is embedded in the xml declaration; so we have to
364  * parse that before converting to server encoding.
365  */
366  nbytes = buf->len - buf->cursor;
367  str = (char *) pq_getmsgbytes(buf, nbytes);
368 
369  /*
370  * We need a null-terminated string to pass to parse_xml_decl(). Rather
371  * than make a separate copy, make the temporary result one byte bigger
372  * than it needs to be.
373  */
374  result = palloc(nbytes + 1 + VARHDRSZ);
375  SET_VARSIZE(result, nbytes + VARHDRSZ);
376  memcpy(VARDATA(result), str, nbytes);
377  str = VARDATA(result);
378  str[nbytes] = '\0';
379 
380  parse_xml_decl((const xmlChar *) str, NULL, NULL, &encodingStr, NULL);
381 
382  /*
383  * If encoding wasn't explicitly specified in the XML header, treat it as
384  * UTF-8, as that's the default in XML. This is different from xml_in(),
385  * where the input has to go through the normal client to server encoding
386  * conversion.
387  */
388  encoding = encodingStr ? xmlChar_to_encoding(encodingStr) : PG_UTF8;
389 
390  /*
391  * Parse the data to check if it is well-formed XML data. Assume that
392  * xml_parse will throw ERROR if not.
393  */
394  doc = xml_parse(result, xmloption, true, encoding);
395  xmlFreeDoc(doc);
396 
397  /* Now that we know what we're dealing with, convert to server encoding */
398  newstr = pg_any_to_server(str, nbytes, encoding);
399 
400  if (newstr != str)
401  {
402  pfree(result);
403  result = (xmltype *) cstring_to_text(newstr);
404  pfree(newstr);
405  }
406 
407  PG_RETURN_XML_P(result);
408 #else
409  NO_XML_SUPPORT();
410  return 0;
411 #endif
412 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:445
StringInfoData * StringInfo
Definition: stringinfo.h:43
return result
Definition: formatting.c:1633
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:550
void pfree(void *pointer)
Definition: mcxt.c:950
static char * buf
Definition: pg_test_fsync.c:66
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static char * encoding
Definition: initdb.c:122
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define NULL
Definition: c.h:229
void * palloc(Size size)
Definition: mcxt.c:849
int xmloption
Definition: xml.c:97
Definition: c.h:439
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:572
Datum xml_send ( PG_FUNCTION_ARGS  )

Definition at line 416 of file xml.c.

References buf, pfree(), pg_get_client_encoding(), PG_GETARG_XML_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), and xml_out_internal().

417 {
418  xmltype *x = PG_GETARG_XML_P(0);
419  char *outval;
421 
422  /*
423  * xml_out_internal doesn't convert the encoding, it just prints the right
424  * declaration. pq_sendtext will do the conversion.
425  */
427 
428  pq_begintypsend(&buf);
429  pq_sendtext(&buf, outval, strlen(outval));
430  pfree(outval);
432 }
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:163
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
void pfree(void *pointer)
Definition: mcxt.c:950
static char * buf
Definition: pg_test_fsync.c:66
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
int pg_get_client_encoding(void)
Definition: mbutils.c:317
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:291
Definition: c.h:439
Datum xmlcomment ( PG_FUNCTION_ARGS  )

Definition at line 469 of file xml.c.

References appendStringInfoString(), appendStringInfoText(), arg, buf, ereport, errcode(), errmsg(), ERROR, i, initStringInfo(), NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

470 {
471 #ifdef USE_LIBXML
472  text *arg = PG_GETARG_TEXT_PP(0);
473  char *argdata = VARDATA_ANY(arg);
474  int len = VARSIZE_ANY_EXHDR(arg);
476  int i;
477 
478  /* check for "--" in string or "-" at the end */
479  for (i = 1; i < len; i++)
480  {
481  if (argdata[i] == '-' && argdata[i - 1] == '-')
482  ereport(ERROR,
483  (errcode(ERRCODE_INVALID_XML_COMMENT),
484  errmsg("invalid XML comment")));
485  }
486  if (len > 0 && argdata[len - 1] == '-')
487  ereport(ERROR,
488  (errcode(ERRCODE_INVALID_XML_COMMENT),
489  errmsg("invalid XML comment")));
490 
491  initStringInfo(&buf);
492  appendStringInfoString(&buf, "<!--");
493  appendStringInfoText(&buf, arg);
494  appendStringInfoString(&buf, "-->");
495 
497 #else
498  NO_XML_SUPPORT();
499  return 0;
500 #endif
501 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ERROR
Definition: elog.h:43
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3673
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define ereport(elevel, rest)
Definition: elog.h:122
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:445
int i
void * arg
Definition: c.h:439
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
Datum xmlconcat2 ( PG_FUNCTION_ARGS  )

Definition at line 576 of file xml.c.

References list_make2, PG_ARGISNULL, PG_GETARG_XML_P, PG_RETURN_NULL, PG_RETURN_XML_P, and xmlconcat().

577 {
578  if (PG_ARGISNULL(0))
579  {
580  if (PG_ARGISNULL(1))
581  PG_RETURN_NULL();
582  else
584  }
585  else if (PG_ARGISNULL(1))
587  else
589  PG_GETARG_XML_P(1))));
590 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
xmltype * xmlconcat(List *args)
Definition: xml.c:510
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define PG_RETURN_NULL()
Definition: fmgr.h:305
static void xmldata_root_element_end ( StringInfo  result,
const char *  eltname 
)
static

Definition at line 2525 of file xml.c.

References appendStringInfo().

Referenced by cursor_to_xml(), database_to_xml_internal(), query_to_xml_internal(), schema_to_xml_internal(), and SPI_sql_row_to_xmlelement().

2526 {
2527  appendStringInfo(result, "</%s>\n", eltname);
2528 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
static void xmldata_root_element_start ( StringInfo  result,
const char *  eltname,
const char *  xmlschema,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2498 of file xml.c.

References appendStringInfo(), appendStringInfoString(), Assert, and NAMESPACE_XSI.

Referenced by cursor_to_xml(), database_to_xml_internal(), query_to_xml_internal(), schema_to_xml_internal(), and SPI_sql_row_to_xmlelement().

2501 {
2502  /* This isn't really wrong but currently makes no sense. */
2503  Assert(top_level || !xmlschema);
2504 
2505  appendStringInfo(result, "<%s", eltname);
2506  if (top_level)
2507  {
2508  appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2509  if (strlen(targetns) > 0)
2510  appendStringInfo(result, " xmlns=\"%s\"", targetns);
2511  }
2512  if (xmlschema)
2513  {
2514  /* FIXME: better targets */
2515  if (strlen(targetns) > 0)
2516  appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2517  else
2518  appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2519  }
2520  appendStringInfoString(result, ">\n");
2521 }
#define NAMESPACE_XSI
Definition: xml.c:227
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
#define Assert(condition)
Definition: c.h:675
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)
Datum xmlexists ( PG_FUNCTION_ARGS  )

Definition at line 4036 of file xml.c.

References NO_XML_SUPPORT, NULL, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, and PG_RETURN_BOOL.

4037 {
4038 #ifdef USE_LIBXML
4039  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4040  xmltype *data = PG_GETARG_XML_P(1);
4041  int res_nitems;
4042 
4043  xpath_internal(xpath_expr_text, data, NULL,
4044  &res_nitems, NULL);
4045 
4046  PG_RETURN_BOOL(res_nitems > 0);
4047 #else
4048  NO_XML_SUPPORT();
4049  return 0;
4050 #endif
4051 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define NULL
Definition: c.h:229
Definition: c.h:439
xmltype* xmlparse ( text data,
XmlOptionType  xmloption_arg,
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
static void XmlTableDestroyOpaque ( struct TableFuncScanState state)
static

Definition at line 4596 of file xml.c.

References i, NO_XML_SUPPORT, NULL, TableFuncScanState::opaque, and pg_xml_done().

4597 {
4598 #ifdef USE_LIBXML
4599  XmlTableBuilderData *xtCxt;
4600 
4601  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
4602 
4603  /* Propagate context related error context to libxml2 */
4604  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4605 
4606  if (xtCxt->xpathscomp != NULL)
4607  {
4608  int i;
4609 
4610  for (i = 0; i < xtCxt->natts; i++)
4611  if (xtCxt->xpathscomp[i] != NULL)
4612  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
4613  }
4614 
4615  if (xtCxt->xpathobj != NULL)
4616  xmlXPathFreeObject(xtCxt->xpathobj);
4617  if (xtCxt->xpathcomp != NULL)
4618  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
4619  if (xtCxt->xpathcxt != NULL)
4620  xmlXPathFreeContext(xtCxt->xpathcxt);
4621  if (xtCxt->doc != NULL)
4622  xmlFreeDoc(xtCxt->doc);
4623  if (xtCxt->ctxt != NULL)
4624  xmlFreeParserCtxt(xtCxt->ctxt);
4625 
4626  pg_xml_done(xtCxt->xmlerrcxt, true);
4627 
4628  /* not valid anymore */
4629  xtCxt->magic = 0;
4630  state->opaque = NULL;
4631 
4632 #else
4633  NO_XML_SUPPORT();
4634 #endif /* not USE_LIBXML */
4635 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
#define NULL
Definition: c.h:229
int i
static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4379 of file xml.c.

References ERROR, NO_XML_SUPPORT, NULL, and xml_ereport().

4380 {
4381 #ifdef USE_LIBXML
4382  XmlTableBuilderData *xtCxt;
4383 
4384  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4385 
4386  /*
4387  * XmlTable returns table - set of composite values. The error context, is
4388  * used for producement more values, between two calls, there can be
4389  * created and used another libxml2 error context. It is libxml2 global
4390  * value, so it should be refreshed any time before any libxml2 usage,
4391  * that is finished by returning some value.
4392  */
4393  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4394 
4395  if (xtCxt->xpathobj == NULL)
4396  {
4397  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4398  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4399  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4400  "could not create XPath object");
4401 
4402  xtCxt->row_count = 0;
4403  }
4404 
4405  if (xtCxt->xpathobj->type == XPATH_NODESET)
4406  {
4407  if (xtCxt->xpathobj->nodesetval != NULL)
4408  {
4409  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4410  return true;
4411  }
4412  }
4413 
4414  return false;
4415 #else
4416  NO_XML_SUPPORT();
4417  return false;
4418 #endif /* not USE_LIBXML */
4419 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define ERROR
Definition: elog.h:43
#define NULL
Definition: c.h:229
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
static Datum XmlTableGetValue ( struct TableFuncScanState state,
int  colnum,
Oid  typid,
int32  typmod,
bool isnull 
)
static

Definition at line 4430 of file xml.c.

References appendStringInfoText(), Assert, cur, StringInfoData::data, elog, ereport, errcode(), errmsg(), ERROR, i, TableFuncScanState::in_functions, initStringInfo(), InputFunctionCall(), NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pstrdup(), result, text_to_cstring(), TableFuncScanState::typioparams, xml_ereport(), and XMLOID.

4432 {
4433 #ifdef USE_LIBXML
4434  XmlTableBuilderData *xtCxt;
4435  Datum result = (Datum) 0;
4436  xmlNodePtr cur;
4437  char *cstr = NULL;
4438  volatile xmlXPathObjectPtr xpathobj = NULL;
4439 
4440  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4441 
4442  Assert(xtCxt->xpathobj &&
4443  xtCxt->xpathobj->type == XPATH_NODESET &&
4444  xtCxt->xpathobj->nodesetval != NULL);
4445 
4446  /* Propagate context related error context to libxml2 */
4447  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4448 
4449  *isnull = false;
4450 
4451  cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
4452 
4453  Assert(xtCxt->xpathscomp[colnum] != NULL);
4454 
4455  PG_TRY();
4456  {
4457  /* Set current node as entry point for XPath evaluation */
4458  xtCxt->xpathcxt->node = cur;
4459 
4460  /* Evaluate column path */
4461  xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
4462  if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4463  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4464  "could not create XPath object");
4465 
4466  /*
4467  * There are four possible cases, depending on the number of nodes
4468  * returned by the XPath expression and the type of the target column:
4469  * a) XPath returns no nodes. b) One node is returned, and column is
4470  * of type XML. c) One node, column type other than XML. d) Multiple
4471  * nodes are returned.
4472  */
4473  if (xpathobj->type == XPATH_NODESET)
4474  {
4475  int count = 0;
4476 
4477  if (xpathobj->nodesetval != NULL)
4478  count = xpathobj->nodesetval->nodeNr;
4479 
4480  if (xpathobj->nodesetval == NULL || count == 0)
4481  {
4482  *isnull = true;
4483  }
4484  else if (count == 1 && typid == XMLOID)
4485  {
4486  text *textstr;
4487 
4488  /* simple case, result is one value */
4489  textstr = xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[0],
4490  xtCxt->xmlerrcxt);
4491  cstr = text_to_cstring(textstr);
4492  }
4493  else if (count == 1)
4494  {
4495  xmlChar *str;
4496 
4497  str = xmlNodeListGetString(xtCxt->doc,
4498  xpathobj->nodesetval->nodeTab[0]->xmlChildrenNode,
4499  1);
4500 
4501  if (str != NULL)
4502  {
4503  PG_TRY();
4504  {
4505  cstr = pstrdup((char *) str);
4506  }
4507  PG_CATCH();
4508  {
4509  xmlFree(str);
4510  PG_RE_THROW();
4511  }
4512  PG_END_TRY();
4513  xmlFree(str);
4514  }
4515  else
4516  {
4517  /*
4518  * This line ensure mapping of empty tags to PostgreSQL
4519  * value. Usually we would to map a empty tag to empty
4520  * string. But this mapping can create empty string when
4521  * user doesn't expect it - when empty tag is enforced by
4522  * libxml2 - when user uses a text() function for example.
4523  */
4524  cstr = "";
4525  }
4526  }
4527  else
4528  {
4529  StringInfoData str;
4530  int i;
4531 
4532  Assert(count > 1);
4533 
4534  /*
4535  * When evaluating the XPath expression returns multiple
4536  * nodes, the result is the concatenation of them all. The
4537  * target type must be XML.
4538  */
4539  if (typid != XMLOID)
4540  ereport(ERROR,
4541  (errcode(ERRCODE_CARDINALITY_VIOLATION),
4542  errmsg("more than one value returned by column XPath expression")));
4543 
4544  /* Concatenate serialized values */
4545  initStringInfo(&str);
4546  for (i = 0; i < count; i++)
4547  {
4548  appendStringInfoText(&str,
4549  xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
4550  xtCxt->xmlerrcxt));
4551  }
4552  cstr = str.data;
4553  }
4554  }
4555  else if (xpathobj->type == XPATH_STRING)
4556  {
4557  cstr = (char *) xpathobj->stringval;
4558  }
4559  else
4560  elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
4561 
4562  /*
4563  * By here, either cstr contains the result value, or the isnull flag
4564  * has been set.
4565  */
4566  Assert(cstr || *isnull);
4567 
4568  if (!*isnull)
4569  result = InputFunctionCall(&state->in_functions[colnum],
4570  cstr,
4571  state->typioparams[colnum],
4572  typmod);
4573  }
4574  PG_CATCH();
4575  {
4576  if (xpathobj != NULL)
4577  xmlXPathFreeObject(xpathobj);
4578  PG_RE_THROW();
4579  }
4580  PG_END_TRY();
4581 
4582  xmlXPathFreeObject(xpathobj);
4583 
4584  return result;
4585 #else
4586  NO_XML_SUPPORT();
4587  return 0;
4588 #endif /* not USE_LIBXML */
4589 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
char * pstrdup(const char *in)
Definition: mcxt.c:1077
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
#define ERROR
Definition: elog.h:43
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3673
#define XMLOID
Definition: pg_type.h:359
#define ereport(elevel, rest)
Definition: elog.h:122
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uintptr_t Datum
Definition: postgres.h:372
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1623
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
FmgrInfo * in_functions
Definition: execnodes.h:1448
#define PG_RE_THROW()
Definition: elog.h:314
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: c.h:439
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
static void XmlTableInitOpaque ( struct TableFuncScanState state,
int  natts 
)
static

Definition at line 4184 of file xml.c.

References ERROR, NO_XML_SUPPORT, NULL, TableFuncScanState::opaque, palloc0(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, and xml_ereport().

4185 {
4186 #ifdef USE_LIBXML
4187  volatile xmlParserCtxtPtr ctxt = NULL;
4188  XmlTableBuilderData *xtCxt;
4189  PgXmlErrorContext *xmlerrcxt;
4190 
4191  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4192  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4193  xtCxt->natts = natts;
4194  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4195 
4196  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4197 
4198  PG_TRY();
4199  {
4200  xmlInitParser();
4201 
4202  ctxt = xmlNewParserCtxt();
4203  if (ctxt == NULL || xmlerrcxt->err_occurred)
4204  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4205  "could not allocate parser context");
4206  }
4207  PG_CATCH();
4208  {
4209  if (ctxt != NULL)
4210  xmlFreeParserCtxt(ctxt);
4211 
4212  pg_xml_done(xmlerrcxt, true);
4213 
4214  PG_RE_THROW();
4215  }
4216  PG_END_TRY();
4217 
4218  xtCxt->xmlerrcxt = xmlerrcxt;
4219  xtCxt->ctxt = ctxt;
4220 
4221  state->opaque = xtCxt;
4222 #else
4223  NO_XML_SUPPORT();
4224 #endif /* not USE_LIBXML */
4225 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
#define ERROR
Definition: elog.h:43
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
void * palloc0(Size size)
Definition: mcxt.c:878
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:229
#define PG_RE_THROW()
Definition: elog.h:314
#define PG_TRY()
Definition: elog.h:284
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)
static void XmlTableSetColumnFilter ( struct TableFuncScanState state,
char *  path,
int  colnum 
)
static

Definition at line 4347 of file xml.c.

References AssertArg, ereport, errcode(), errmsg(), ERROR, NO_XML_SUPPORT, NULL, PointerIsValid, and xml_ereport().

4348 {
4349 #ifdef USE_LIBXML
4350  XmlTableBuilderData *xtCxt;
4351  xmlChar *xstr;
4352 
4353  AssertArg(PointerIsValid(path));
4354 
4355  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4356 
4357  if (*path == '\0')
4358  ereport(ERROR,
4359  (errcode(ERRCODE_DATA_EXCEPTION),
4360  errmsg("column path filter must not be empty string")));
4361 
4362  xstr = pg_xmlCharStrndup(path, strlen(path));
4363 
4364  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4365  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4366  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4367  "invalid XPath expression");
4368 #else
4369  NO_XML_SUPPORT();
4370 #endif /* not USE_LIBXML */
4371 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define AssertArg(condition)
Definition: c.h:677
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PointerIsValid(pointer)
Definition: c.h:526
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
static void XmlTableSetDocument ( struct TableFuncScanState state,
Datum  value 
)
static

Definition at line 4232 of file xml.c.

References DatumGetXmlP, ERROR, length(), NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, xml_ereport(), and xml_out_internal().

4233 {
4234 #ifdef USE_LIBXML
4235  XmlTableBuilderData *xtCxt;
4236  xmltype *xmlval = DatumGetXmlP(value);
4237  char *str;
4238  xmlChar *xstr;
4239  int length;
4240  volatile xmlDocPtr doc = NULL;
4241  volatile xmlXPathContextPtr xpathcxt = NULL;
4242 
4243  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4244 
4245  /*
4246  * Use out function for casting to string (remove encoding property). See
4247  * comment in xml_out.
4248  */
4249  str = xml_out_internal(xmlval, 0);
4250 
4251  length = strlen(str);
4252  xstr = pg_xmlCharStrndup(str, length);
4253 
4254  PG_TRY();
4255  {
4256  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4257  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4258  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4259  "could not parse XML document");
4260  xpathcxt = xmlXPathNewContext(doc);
4261  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4262  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4263  "could not allocate XPath context");
4264  xpathcxt->node = xmlDocGetRootElement(doc);
4265  if (xpathcxt->node == NULL || xtCxt->xmlerrcxt->err_occurred)
4266  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4267  "could not find root XML element");
4268  }
4269  PG_CATCH();
4270  {
4271  if (xpathcxt != NULL)
4272  xmlXPathFreeContext(xpathcxt);
4273  if (doc != NULL)
4274  xmlFreeDoc(doc);
4275 
4276  PG_RE_THROW();
4277  }
4278  PG_END_TRY();
4279 
4280  xtCxt->doc = doc;
4281  xtCxt->xpathcxt = xpathcxt;
4282 #else
4283  NO_XML_SUPPORT();
4284 #endif /* not USE_LIBXML */
4285 }
int length(const List *list)
Definition: list.c:1271
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define DatumGetXmlP(X)
Definition: xml.h:50
#define ERROR
Definition: elog.h:43
static struct @121 value
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:291
#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
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
static void XmlTableSetNamespace ( struct TableFuncScanState state,
char *  name,
char *  uri 
)
static

Definition at line 4292 of file xml.c.

References ereport, errcode(), errmsg(), ERROR, NO_XML_SUPPORT, NULL, and xml_ereport().

4293 {
4294 #ifdef USE_LIBXML
4295  XmlTableBuilderData *xtCxt;
4296 
4297  if (name == NULL)
4298  ereport(ERROR,
4299  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4300  errmsg("DEFAULT namespace is not supported")));
4301  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4302 
4303  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4304  pg_xmlCharStrndup(name, strlen(name)),
4305  pg_xmlCharStrndup(uri, strlen(uri))))
4306  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4307  "could not set XML namespace");
4308 #else
4309  NO_XML_SUPPORT();
4310 #endif /* not USE_LIBXML */
4311 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
static void XmlTableSetRowFilter ( struct TableFuncScanState state,
char *  path 
)
static

Definition at line 4318 of file xml.c.

References ereport, errcode(), errmsg(), ERROR, NO_XML_SUPPORT, NULL, and xml_ereport().

4319 {
4320 #ifdef USE_LIBXML
4321  XmlTableBuilderData *xtCxt;
4322  xmlChar *xstr;
4323 
4324  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4325 
4326  if (*path == '\0')
4327  ereport(ERROR,
4328  (errcode(ERRCODE_DATA_EXCEPTION),
4329  errmsg("row path filter must not be empty string")));
4330 
4331  xstr = pg_xmlCharStrndup(path, strlen(path));
4332 
4333  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4334  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4335  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4336  "invalid XPath expression");
4337 #else
4338  NO_XML_SUPPORT();
4339 #endif /* not USE_LIBXML */
4340 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 603 of file xml.c.

References PG_GETARG_XML_P, and PG_RETURN_TEXT_P.

604 {
605  xmltype *data = PG_GETARG_XML_P(0);
606 
607  /* It's actually binary compatible. */
608  PG_RETURN_TEXT_P((text *) data);
609 }
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
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
Datum xmlvalidate ( PG_FUNCTION_ARGS  )

Definition at line 876 of file xml.c.

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

877 {
878  ereport(ERROR,
879  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
880  errmsg("xmlvalidate is not implemented")));
881  return 0;
882 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4013 of file xml.c.

References CurrentMemoryContext, initArrayResult(), makeArrayResult(), NO_XML_SUPPORT, NULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, PG_RETURN_ARRAYTYPE_P, and XMLOID.

Referenced by xpath_bool(), xpath_list(), xpath_nodeset(), xpath_number(), and xpath_string().

4014 {
4015 #ifdef USE_LIBXML
4016  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4017  xmltype *data = PG_GETARG_XML_P(1);
4018  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4019  ArrayBuildState *astate;
4020 
4021  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4022  xpath_internal(xpath_expr_text, data, namespaces,
4023  NULL, astate);
4025 #else
4026  NO_XML_SUPPORT();
4027  return 0;
4028 #endif
4029 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:4951
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:244
#define XMLOID
Definition: pg_type.h:359
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:246
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5054
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define NULL
Definition: c.h:229
Definition: c.h:439
Datum xpath_exists ( PG_FUNCTION_ARGS  )

Definition at line 4059 of file xml.c.

References NO_XML_SUPPORT, NULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, and PG_RETURN_BOOL.

4060 {
4061 #ifdef USE_LIBXML
4062  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4063  xmltype *data = PG_GETARG_XML_P(1);
4064  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4065  int res_nitems;
4066 
4067  xpath_internal(xpath_expr_text, data, namespaces,
4068  &res_nitems, NULL);
4069 
4070  PG_RETURN_BOOL(res_nitems > 0);
4071 #else
4072  NO_XML_SUPPORT();
4073  return 0;
4074 #endif
4075 }
#define NO_XML_SUPPORT()
Definition: xml.c:217
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:244
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define NULL
Definition: c.h:229
Definition: c.h:439
static void xsd_schema_element_end ( StringInfo  result)
static

Definition at line 2790 of file xml.c.

References appendStringInfoString().

Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().

2791 {
2792  appendStringInfoString(result, "</xsd:schema>");
2793 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static void xsd_schema_element_start ( StringInfo  result,
const char *  targetns 
)
static

Definition at line 2773 of file xml.c.

References appendStringInfo(), appendStringInfoString(), and NAMESPACE_XSD.

Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().

2774 {
2775  appendStringInfoString(result,
2776  "<xsd:schema\n"
2777  " xmlns:xsd=\"" NAMESPACE_XSD "\"");
2778  if (strlen(targetns) > 0)
2779  appendStringInfo(result,
2780  "\n"
2781  " targetNamespace=\"%s\"\n"
2782  " elementFormDefault=\"qualified\"",
2783  targetns);
2784  appendStringInfoString(result,
2785  ">\n\n");
2786 }
#define NAMESPACE_XSD
Definition: xml.c:226
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157

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
Initial value:
=
{
}
static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts)
Definition: xml.c:4184
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4379
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4232
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4430
static void XmlTableSetRowFilter(struct TableFuncScanState *state, char *path)
Definition: xml.c:4318
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:4596
static void XmlTableSetNamespace(struct TableFuncScanState *state, char *name, char *uri)
Definition: xml.c:4292
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, char *path, int colnum)
Definition: xml.c:4347

Definition at line 205 of file xml.c.

Referenced by ExecInitTableFuncScan().