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

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

Definition at line 222 of file xml.c.

Referenced by xsd_schema_element_start().

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

Definition at line 223 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 213 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 276 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 2365 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 2363 of file xml.c.

Function Documentation

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2260 of file xml.c.

References SPI_palloc().

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

2261 {
2262  size_t len = strlen(s) + 1;
2263  char *ret = SPI_palloc(len);
2264 
2265  memcpy(ret, s, len);
2266  return ret;
2267 }
void * SPI_palloc(Size size)
Definition: spi.c:921
static xmltype* cstring_to_xmltype ( const char *  string)
static

Definition at line 448 of file xml.c.

References cstring_to_text().

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

449 {
450  return (xmltype *) cstring_to_text(string);
451 }
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 2440 of file xml.c.

References 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(), and text_to_cstring().

2441 {
2444  bool nulls = PG_GETARG_BOOL(2);
2445  bool tableforest = PG_GETARG_BOOL(3);
2446  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2447 
2449  Portal portal;
2450  uint64 i;
2451 
2452  initStringInfo(&result);
2453 
2454  SPI_connect();
2455  portal = SPI_cursor_find(name);
2456  if (portal == NULL)
2457  ereport(ERROR,
2458  (errcode(ERRCODE_UNDEFINED_CURSOR),
2459  errmsg("cursor \"%s\" does not exist", name)));
2460 
2461  SPI_cursor_fetch(portal, true, count);
2462  for (i = 0; i < SPI_processed; i++)
2463  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2464  tableforest, targetns, true);
2465 
2466  SPI_finish();
2467 
2469 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
#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:1331
#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 initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#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 xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
int i
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1343
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:3597
Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2612 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.

2613 {
2615  bool nulls = PG_GETARG_BOOL(1);
2616  bool tableforest = PG_GETARG_BOOL(2);
2617  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2618  const char *xmlschema;
2619  Portal portal;
2620 
2621  SPI_connect();
2622  portal = SPI_cursor_find(name);
2623  if (portal == NULL)
2624  ereport(ERROR,
2625  (errcode(ERRCODE_UNDEFINED_CURSOR),
2626  errmsg("cursor \"%s\" does not exist", name)));
2627 
2628  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2629  InvalidOid, nulls,
2630  tableforest, targetns));
2631  SPI_finish();
2632 
2633  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
2634 }
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
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:1331
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2260
#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:3030
#define ereport(elevel, rest)
Definition: elog.h:122
TupleDesc tupDesc
Definition: portal.h:154
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:448
#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 2369 of file xml.c.

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

2370 {
2371  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2372 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2317
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2365
static List* database_get_xml_visible_tables ( void  )
static

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

2377 {
2378  /* At the moment there is no order required here. */
2379  return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2380  " WHERE relkind IN ("
2384  " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2385  " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2386 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2317
#define RELKIND_MATVIEW
Definition: pg_class.h:165
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2365
#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 2913 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().

2914 {
2915  bool nulls = PG_GETARG_BOOL(0);
2916  bool tableforest = PG_GETARG_BOOL(1);
2917  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2918 
2920  tableforest, targetns)));
2921 }
#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:2870
#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:441
Datum database_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

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

2981 {
2982  bool nulls = PG_GETARG_BOOL(0);
2983  bool tableforest = PG_GETARG_BOOL(1);
2984  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2985  StringInfo xmlschema;
2986 
2987  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
2988 
2990  nulls, tableforest, targetns)));
2991 }
#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:2870
#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:2925
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
static StringInfo database_to_xml_internal ( const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

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

2872 {
2874  List *nspid_list;
2875  ListCell *cell;
2876  char *xmlcn;
2877 
2879  true, false);
2880  result = makeStringInfo();
2881 
2882  xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
2883  appendStringInfoChar(result, '\n');
2884 
2885  if (xmlschema)
2886  appendStringInfo(result, "%s\n\n", xmlschema);
2887 
2888  SPI_connect();
2889 
2890  nspid_list = database_get_xml_visible_schemas();
2891 
2892  foreach(cell, nspid_list)
2893  {
2894  Oid nspid = lfirst_oid(cell);
2895  StringInfo subres;
2896 
2897  subres = schema_to_xml_internal(nspid, NULL, nulls,
2898  tableforest, targetns, false);
2899 
2900  appendStringInfoString(result, subres->data);
2901  appendStringInfoChar(result, '\n');
2902  }
2903 
2904  SPI_finish();
2905 
2906  xmldata_root_element_end(result, xmlcn);
2907 
2908  return result;
2909 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2485
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2695
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
return result
Definition: formatting.c:1618
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:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2369
Oid MyDatabaseId
Definition: globals.c:76
#define NULL
Definition: c.h:229
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2512
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

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

2969 {
2970  bool nulls = PG_GETARG_BOOL(0);
2971  bool tableforest = PG_GETARG_BOOL(1);
2972  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
2973 
2975  tableforest, targetns)));
2976 }
#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:2925
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
static StringInfo database_to_xmlschema_internal ( bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

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

2927 {
2928  List *relid_list;
2929  List *nspid_list;
2930  List *tupdesc_list;
2931  ListCell *cell;
2933 
2934  result = makeStringInfo();
2935 
2936  xsd_schema_element_start(result, targetns);
2937 
2938  SPI_connect();
2939 
2940  relid_list = database_get_xml_visible_tables();
2941  nspid_list = database_get_xml_visible_schemas();
2942 
2943  tupdesc_list = NIL;
2944  foreach(cell, relid_list)
2945  {
2946  Relation rel;
2947 
2948  rel = heap_open(lfirst_oid(cell), AccessShareLock);
2949  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2950  heap_close(rel, NoLock);
2951  }
2952 
2953  appendStringInfoString(result,
2954  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2955 
2956  appendStringInfoString(result,
2957  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
2958 
2959  xsd_schema_element_end(result);
2960 
2961  SPI_finish();
2962 
2963  return result;
2964 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2760
#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:147
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
#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:3206
return result
Definition: formatting.c:1618
#define heap_close(r, l)
Definition: heapam.h:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
#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:3368
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2369
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2777
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:2376
char* escape_xml ( const char *  str)

Definition at line 2228 of file xml.c.

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

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

2229 {
2231  const char *p;
2232 
2233  initStringInfo(&buf);
2234  for (p = str; *p; p++)
2235  {
2236  switch (*p)
2237  {
2238  case '&':
2239  appendStringInfoString(&buf, "&amp;");
2240  break;
2241  case '<':
2242  appendStringInfoString(&buf, "&lt;");
2243  break;
2244  case '>':
2245  appendStringInfoString(&buf, "&gt;");
2246  break;
2247  case '\r':
2248  appendStringInfoString(&buf, "&#x0d;");
2249  break;
2250  default:
2251  appendStringInfoCharMacro(&buf, *p);
2252  break;
2253  }
2254  }
2255  return buf.data;
2256 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:135
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
static char* map_multipart_sql_identifier_to_xml_name ( char *  a,
char *  b,
char *  c,
char *  d 
)
static

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

3000 {
3002 
3003  initStringInfo(&result);
3004 
3005  if (a)
3006  appendStringInfoString(&result,
3007  map_sql_identifier_to_xml_name(a, true, true));
3008  if (b)
3009  appendStringInfo(&result, ".%s",
3010  map_sql_identifier_to_xml_name(b, true, true));
3011  if (c)
3012  appendStringInfo(&result, ".%s",
3013  map_sql_identifier_to_xml_name(c, true, true));
3014  if (d)
3015  appendStringInfo(&result, ".%s",
3016  map_sql_identifier_to_xml_name(d, true, true));
3017 
3018  return result.data;
3019 }
return result
Definition: formatting.c:1618
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
char * c
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
static const char * map_sql_catalog_to_xmlschema_types ( List nspid_list,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

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

3208 {
3209  char *dbname;
3210  char *xmlcn;
3211  char *catalogtypename;
3213  ListCell *cell;
3214 
3215  dbname = get_database_name(MyDatabaseId);
3216 
3217  initStringInfo(&result);
3218 
3219  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3220 
3221  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3222  dbname,
3223  NULL,
3224  NULL);
3225 
3226  appendStringInfo(&result,
3227  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3228  appendStringInfoString(&result,
3229  " <xsd:all>\n");
3230 
3231  foreach(cell, nspid_list)
3232  {
3233  Oid nspid = lfirst_oid(cell);
3234  char *nspname = get_namespace_name(nspid);
3235  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3236  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3237  dbname,
3238  nspname,
3239  NULL);
3240 
3241  appendStringInfo(&result,
3242  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3243  xmlsn, schematypename);
3244  }
3245 
3246  appendStringInfoString(&result,
3247  " </xsd:all>\n");
3248  appendStringInfoString(&result,
3249  "</xsd:complexType>\n\n");
3250 
3251  appendStringInfo(&result,
3252  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3253  xmlcn, catalogtypename);
3254 
3255  return result.data;
3256 }
return result
Definition: formatting.c:1618
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:2999
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
Oid MyDatabaseId
Definition: globals.c:76
#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 1893 of file xml.c.

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

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

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

3135 {
3136  char *dbname;
3137  char *nspname;
3138  char *xmlsn;
3139  char *schematypename;
3141  ListCell *cell;
3142 
3143  dbname = get_database_name(MyDatabaseId);
3144  nspname = get_namespace_name(nspid);
3145 
3146  initStringInfo(&result);
3147 
3148  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3149 
3150  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3151  dbname,
3152  nspname,
3153  NULL);
3154 
3155  appendStringInfo(&result,
3156  "<xsd:complexType name=\"%s\">\n", schematypename);
3157  if (!tableforest)
3158  appendStringInfoString(&result,
3159  " <xsd:all>\n");
3160  else
3161  appendStringInfoString(&result,
3162  " <xsd:sequence>\n");
3163 
3164  foreach(cell, relid_list)
3165  {
3166  Oid relid = lfirst_oid(cell);
3167  char *relname = get_rel_name(relid);
3168  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3169  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3170  dbname,
3171  nspname,
3172  relname);
3173 
3174  if (!tableforest)
3175  appendStringInfo(&result,
3176  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3177  xmltn, tabletypename);
3178  else
3179  appendStringInfo(&result,
3180  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3181  xmltn, tabletypename);
3182  }
3183 
3184  if (!tableforest)
3185  appendStringInfoString(&result,
3186  " </xsd:all>\n");
3187  else
3188  appendStringInfoString(&result,
3189  " </xsd:sequence>\n");
3190  appendStringInfoString(&result,
3191  "</xsd:complexType>\n\n");
3192 
3193  appendStringInfo(&result,
3194  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3195  xmlsn, schematypename);
3196 
3197  return result.data;
3198 }
return result
Definition: formatting.c:1618
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:2999
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
Oid MyDatabaseId
Definition: globals.c:76
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
#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 3030 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().

3032 {
3033  int i;
3034  char *xmltn;
3035  char *tabletypename;
3036  char *rowtypename;
3038 
3039  initStringInfo(&result);
3040 
3041  if (OidIsValid(relid))
3042  {
3043  HeapTuple tuple;
3044  Form_pg_class reltuple;
3045 
3046  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3047  if (!HeapTupleIsValid(tuple))
3048  elog(ERROR, "cache lookup failed for relation %u", relid);
3049  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3050 
3051  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3052  true, false);
3053 
3054  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3056  get_namespace_name(reltuple->relnamespace),
3057  NameStr(reltuple->relname));
3058 
3059  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3061  get_namespace_name(reltuple->relnamespace),
3062  NameStr(reltuple->relname));
3063 
3064  ReleaseSysCache(tuple);
3065  }
3066  else
3067  {
3068  if (tableforest)
3069  xmltn = "row";
3070  else
3071  xmltn = "table";
3072 
3073  tabletypename = "TableType";
3074  rowtypename = "RowType";
3075  }
3076 
3077  xsd_schema_element_start(&result, targetns);
3078 
3079  appendStringInfoString(&result,
3081 
3082  appendStringInfo(&result,
3083  "<xsd:complexType name=\"%s\">\n"
3084  " <xsd:sequence>\n",
3085  rowtypename);
3086 
3087  for (i = 0; i < tupdesc->natts; i++)
3088  {
3089  if (tupdesc->attrs[i]->attisdropped)
3090  continue;
3091  appendStringInfo(&result,
3092  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3093  map_sql_identifier_to_xml_name(NameStr(tupdesc->attrs[i]->attname),
3094  true, false),
3095  map_sql_type_to_xml_name(tupdesc->attrs[i]->atttypid, -1),
3096  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3097  }
3098 
3099  appendStringInfoString(&result,
3100  " </xsd:sequence>\n"
3101  "</xsd:complexType>\n\n");
3102 
3103  if (!tableforest)
3104  {
3105  appendStringInfo(&result,
3106  "<xsd:complexType name=\"%s\">\n"
3107  " <xsd:sequence>\n"
3108  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3109  " </xsd:sequence>\n"
3110  "</xsd:complexType>\n\n",
3111  tabletypename, rowtypename);
3112 
3113  appendStringInfo(&result,
3114  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3115  xmltn, tabletypename);
3116  }
3117  else
3118  appendStringInfo(&result,
3119  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3120  xmltn, rowtypename);
3121 
3122  xsd_schema_element_end(&result);
3123 
3124  return result.data;
3125 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2760
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Form_pg_attribute * attrs
Definition: tupdesc.h:74
return result
Definition: formatting.c:1618
static char * map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d)
Definition: xml.c:2999
#define OidIsValid(objectId)
Definition: c.h:538
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#define list_make1(x1)
Definition: pg_list.h:133
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#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:189
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3368
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3263
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2777
Oid MyDatabaseId
Definition: globals.c:76
#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 3263 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().

3264 {
3266 
3267  initStringInfo(&result);
3268 
3269  switch (typeoid)
3270  {
3271  case BPCHAROID:
3272  if (typmod == -1)
3273  appendStringInfoString(&result, "CHAR");
3274  else
3275  appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3276  break;
3277  case VARCHAROID:
3278  if (typmod == -1)
3279  appendStringInfoString(&result, "VARCHAR");
3280  else
3281  appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3282  break;
3283  case NUMERICOID:
3284  if (typmod == -1)
3285  appendStringInfoString(&result, "NUMERIC");
3286  else
3287  appendStringInfo(&result, "NUMERIC_%d_%d",
3288  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3289  (typmod - VARHDRSZ) & 0xffff);
3290  break;
3291  case INT4OID:
3292  appendStringInfoString(&result, "INTEGER");
3293  break;
3294  case INT2OID:
3295  appendStringInfoString(&result, "SMALLINT");
3296  break;
3297  case INT8OID:
3298  appendStringInfoString(&result, "BIGINT");
3299  break;
3300  case FLOAT4OID:
3301  appendStringInfoString(&result, "REAL");
3302  break;
3303  case FLOAT8OID:
3304  appendStringInfoString(&result, "DOUBLE");
3305  break;
3306  case BOOLOID:
3307  appendStringInfoString(&result, "BOOLEAN");
3308  break;
3309  case TIMEOID:
3310  if (typmod == -1)
3311  appendStringInfoString(&result, "TIME");
3312  else
3313  appendStringInfo(&result, "TIME_%d", typmod);
3314  break;
3315  case TIMETZOID:
3316  if (typmod == -1)
3317  appendStringInfoString(&result, "TIME_WTZ");
3318  else
3319  appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3320  break;
3321  case TIMESTAMPOID:
3322  if (typmod == -1)
3323  appendStringInfoString(&result, "TIMESTAMP");
3324  else
3325  appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3326  break;
3327  case TIMESTAMPTZOID:
3328  if (typmod == -1)
3329  appendStringInfoString(&result, "TIMESTAMP_WTZ");
3330  else
3331  appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3332  break;
3333  case DATEOID:
3334  appendStringInfoString(&result, "DATE");
3335  break;
3336  case XMLOID:
3337  appendStringInfoString(&result, "XML");
3338  break;
3339  default:
3340  {
3341  HeapTuple tuple;
3342  Form_pg_type typtuple;
3343 
3344  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3345  if (!HeapTupleIsValid(tuple))
3346  elog(ERROR, "cache lookup failed for type %u", typeoid);
3347  typtuple = (Form_pg_type) GETSTRUCT(tuple);
3348 
3349  appendStringInfoString(&result,
3350  map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3352  get_namespace_name(typtuple->typnamespace),
3353  NameStr(typtuple->typname)));
3354 
3355  ReleaseSysCache(tuple);
3356  }
3357  }
3358 
3359  return result.data;
3360 }
#define TIMESTAMPTZOID
Definition: pg_type.h:521
#define TIMEOID
Definition: pg_type.h:510
#define TYPTYPE_DOMAIN
Definition: pg_type.h:718
#define BPCHAROID
Definition: pg_type.h:500
#define DATEOID
Definition: pg_type.h:507
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define NUMERICOID
Definition: pg_type.h:550
#define VARHDRSZ
Definition: c.h:445
#define INT4OID
Definition: pg_type.h:316
return result
Definition: formatting.c:1618
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:2999
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define TIMESTAMPOID
Definition: pg_type.h:515
#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:189
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define VARCHAROID
Definition: pg_type.h:503
#define FLOAT4OID
Definition: pg_type.h:412
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
Oid MyDatabaseId
Definition: globals.c:76
#define INT8OID
Definition: pg_type.h:304
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define TIMETZOID
Definition: pg_type.h:532
#define FLOAT8OID
Definition: pg_type.h:415
#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 3422 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().

3423 {
3425  const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3426 
3427  initStringInfo(&result);
3428 
3429  if (typeoid == XMLOID)
3430  {
3431  appendStringInfoString(&result,
3432  "<xsd:complexType mixed=\"true\">\n"
3433  " <xsd:sequence>\n"
3434  " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3435  " </xsd:sequence>\n"
3436  "</xsd:complexType>\n");
3437  }
3438  else
3439  {
3440  appendStringInfo(&result,
3441  "<xsd:simpleType name=\"%s\">\n", typename);
3442 
3443  switch (typeoid)
3444  {
3445  case BPCHAROID:
3446  case VARCHAROID:
3447  case TEXTOID:
3448  appendStringInfo(&result,
3449  " <xsd:restriction base=\"xsd:string\">\n");
3450  if (typmod != -1)
3451  appendStringInfo(&result,
3452  " <xsd:maxLength value=\"%d\"/>\n",
3453  typmod - VARHDRSZ);
3454  appendStringInfoString(&result, " </xsd:restriction>\n");
3455  break;
3456 
3457  case BYTEAOID:
3458  appendStringInfo(&result,
3459  " <xsd:restriction base=\"xsd:%s\">\n"
3460  " </xsd:restriction>\n",
3461  xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3462  break;
3463 
3464  case NUMERICOID:
3465  if (typmod != -1)
3466  appendStringInfo(&result,
3467  " <xsd:restriction base=\"xsd:decimal\">\n"
3468  " <xsd:totalDigits value=\"%d\"/>\n"
3469  " <xsd:fractionDigits value=\"%d\"/>\n"
3470  " </xsd:restriction>\n",
3471  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3472  (typmod - VARHDRSZ) & 0xffff);
3473  break;
3474 
3475  case INT2OID:
3476  appendStringInfo(&result,
3477  " <xsd:restriction base=\"xsd:short\">\n"
3478  " <xsd:maxInclusive value=\"%d\"/>\n"
3479  " <xsd:minInclusive value=\"%d\"/>\n"
3480  " </xsd:restriction>\n",
3481  SHRT_MAX, SHRT_MIN);
3482  break;
3483 
3484  case INT4OID:
3485  appendStringInfo(&result,
3486  " <xsd:restriction base=\"xsd:int\">\n"
3487  " <xsd:maxInclusive value=\"%d\"/>\n"
3488  " <xsd:minInclusive value=\"%d\"/>\n"
3489  " </xsd:restriction>\n",
3490  INT_MAX, INT_MIN);
3491  break;
3492 
3493  case INT8OID:
3494  appendStringInfo(&result,
3495  " <xsd:restriction base=\"xsd:long\">\n"
3496  " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3497  " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3498  " </xsd:restriction>\n",
3499  (((uint64) 1) << (sizeof(int64) * 8 - 1)) - 1,
3500  (((uint64) 1) << (sizeof(int64) * 8 - 1)));
3501  break;
3502 
3503  case FLOAT4OID:
3504  appendStringInfoString(&result,
3505  " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3506  break;
3507 
3508  case FLOAT8OID:
3509  appendStringInfoString(&result,
3510  " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3511  break;
3512 
3513  case BOOLOID:
3514  appendStringInfoString(&result,
3515  " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
3516  break;
3517 
3518  case TIMEOID:
3519  case TIMETZOID:
3520  {
3521  const char *tz = (typeoid == TIMETZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3522 
3523  if (typmod == -1)
3524  appendStringInfo(&result,
3525  " <xsd:restriction base=\"xsd:time\">\n"
3526  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3527  " </xsd:restriction>\n", tz);
3528  else if (typmod == 0)
3529  appendStringInfo(&result,
3530  " <xsd:restriction base=\"xsd:time\">\n"
3531  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3532  " </xsd:restriction>\n", tz);
3533  else
3534  appendStringInfo(&result,
3535  " <xsd:restriction base=\"xsd:time\">\n"
3536  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3537  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3538  break;
3539  }
3540 
3541  case TIMESTAMPOID:
3542  case TIMESTAMPTZOID:
3543  {
3544  const char *tz = (typeoid == TIMESTAMPTZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3545 
3546  if (typmod == -1)
3547  appendStringInfo(&result,
3548  " <xsd:restriction base=\"xsd:dateTime\">\n"
3549  " <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"
3550  " </xsd:restriction>\n", tz);
3551  else if (typmod == 0)
3552  appendStringInfo(&result,
3553  " <xsd:restriction base=\"xsd:dateTime\">\n"
3554  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3555  " </xsd:restriction>\n", tz);
3556  else
3557  appendStringInfo(&result,
3558  " <xsd:restriction base=\"xsd:dateTime\">\n"
3559  " <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"
3560  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3561  break;
3562  }
3563 
3564  case DATEOID:
3565  appendStringInfoString(&result,
3566  " <xsd:restriction base=\"xsd:date\">\n"
3567  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
3568  " </xsd:restriction>\n");
3569  break;
3570 
3571  default:
3572  if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
3573  {
3574  Oid base_typeoid;
3575  int32 base_typmod = -1;
3576 
3577  base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
3578 
3579  appendStringInfo(&result,
3580  " <xsd:restriction base=\"%s\"/>\n",
3581  map_sql_type_to_xml_name(base_typeoid, base_typmod));
3582  }
3583  break;
3584  }
3585  appendStringInfoString(&result, "</xsd:simpleType>\n");
3586  }
3587 
3588  return result.data;
3589 }
#define TIMESTAMPTZOID
Definition: pg_type.h:521
#define TIMEOID
Definition: pg_type.h:510
#define TYPTYPE_DOMAIN
Definition: pg_type.h:718
#define BPCHAROID
Definition: pg_type.h:500
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2256
#define DATEOID
Definition: pg_type.h:507
#define TEXTOID
Definition: pg_type.h:324
#define NUMERICOID
Definition: pg_type.h:550
#define VARHDRSZ
Definition: c.h:445
#define INT4OID
Definition: pg_type.h:316
char get_typtype(Oid typid)
Definition: lsyscache.c:2347
return result
Definition: formatting.c:1618
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:110
#define TIMESTAMPOID
Definition: pg_type.h:515
#define INT2OID
Definition: pg_type.h:308
#define XMLOID
Definition: pg_type.h:359
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3263
#define VARCHAROID
Definition: pg_type.h:503
#define FLOAT4OID
Definition: pg_type.h:412
#define INT8OID
Definition: pg_type.h:304
#define TIMETZOID
Definition: pg_type.h:532
#define FLOAT8OID
Definition: pg_type.h:415
#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 3368 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().

3369 {
3370  List *uniquetypes = NIL;
3371  int i;
3373  ListCell *cell0;
3374 
3375  /* extract all column types used in the set of TupleDescs */
3376  foreach(cell0, tupdesc_list)
3377  {
3378  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3379 
3380  for (i = 0; i < tupdesc->natts; i++)
3381  {
3382  if (tupdesc->attrs[i]->attisdropped)
3383  continue;
3384  uniquetypes = list_append_unique_oid(uniquetypes,
3385  tupdesc->attrs[i]->atttypid);
3386  }
3387  }
3388 
3389  /* add base types of domains */
3390  foreach(cell0, uniquetypes)
3391  {
3392  Oid typid = lfirst_oid(cell0);
3393  Oid basetypid = getBaseType(typid);
3394 
3395  if (basetypid != typid)
3396  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3397  }
3398 
3399  /* Convert to textual form */
3400  initStringInfo(&result);
3401 
3402  foreach(cell0, uniquetypes)
3403  {
3404  appendStringInfo(&result, "%s\n",
3406  -1));
3407  }
3408 
3409  return result.data;
3410 }
#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:1618
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
struct tupleDesc * TupleDesc
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define lfirst(lc)
Definition: pg_list.h:106
int i
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2239
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3422
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 2009 of file xml.c.

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

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

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

Definition at line 1969 of file xml.c.

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

Referenced by get_rule_expr().

1970 {
1972  char *p;
1973 
1974  initStringInfo(&buf);
1975 
1976  for (p = name; *p; p += pg_mblen(p))
1977  {
1978  if (*p == '_' && *(p + 1) == 'x'
1979  && isxdigit((unsigned char) *(p + 2))
1980  && isxdigit((unsigned char) *(p + 3))
1981  && isxdigit((unsigned char) *(p + 4))
1982  && isxdigit((unsigned char) *(p + 5))
1983  && *(p + 6) == '_')
1984  {
1985  unsigned int u;
1986 
1987  sscanf(p + 2, "%X", &u);
1989  p += 6;
1990  }
1991  else
1992  appendBinaryStringInfo(&buf, p, pg_mblen(p));
1993  }
1994 
1995  return buf.data;
1996 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771
const char * name
Definition: encode.c:521
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
static char * unicode_to_sqlchar(pg_wchar c)
Definition: xml.c:1949
static List* query_to_oid_list ( const char *  query)
static

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

2318 {
2319  uint64 i;
2320  List *list = NIL;
2321 
2322  SPI_execute(query, true, 0);
2323 
2324  for (i = 0; i < SPI_processed; i++)
2325  {
2326  Datum oid;
2327  bool isnull;
2328 
2329  oid = SPI_getbinval(SPI_tuptable->vals[i],
2331  1,
2332  &isnull);
2333  if (!isnull)
2334  list = lappend_oid(list, DatumGetObjectId(oid));
2335  }
2336 
2337  return list;
2338 }
#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:27
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:835
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc
Definition: spi.h:26
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:303
Datum query_to_xml ( PG_FUNCTION_ARGS  )

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

2427 {
2428  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2429  bool nulls = PG_GETARG_BOOL(1);
2430  bool tableforest = PG_GETARG_BOOL(2);
2431  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2432 
2434  NULL, nulls, tableforest,
2435  targetns, true)));
2436 }
#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:2519
#define NULL
Definition: c.h:229
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
Datum query_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2659 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.

2660 {
2661  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2662  bool nulls = PG_GETARG_BOOL(1);
2663  bool tableforest = PG_GETARG_BOOL(2);
2664  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2665 
2666  const char *xmlschema;
2667  SPIPlanPtr plan;
2668  Portal portal;
2669 
2670  SPI_connect();
2671 
2672  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2673  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2674 
2675  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2676  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2677 
2678  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2679  InvalidOid, nulls, tableforest, targetns));
2680  SPI_cursor_close(portal);
2681  SPI_finish();
2682 
2684  xmlschema, nulls, tableforest,
2685  targetns, true)));
2686 }
int SPI_connect(void)
Definition: spi.c:84
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:481
int SPI_finish(void)
Definition: spi.c:147
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1028
#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:2260
#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:3030
TupleDesc tupDesc
Definition: portal.h:154
#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:2519
#define NULL
Definition: c.h:229
void SPI_cursor_close(Portal portal)
Definition: spi.c:1399
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
#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 2519 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().

2522 {
2524  char *xmltn;
2525  uint64 i;
2526 
2527  if (tablename)
2528  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2529  else
2530  xmltn = "table";
2531 
2532  result = makeStringInfo();
2533 
2534  SPI_connect();
2535  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2536  ereport(ERROR,
2537  (errcode(ERRCODE_DATA_EXCEPTION),
2538  errmsg("invalid query")));
2539 
2540  if (!tableforest)
2541  {
2542  xmldata_root_element_start(result, xmltn, xmlschema,
2543  targetns, top_level);
2544  appendStringInfoChar(result, '\n');
2545  }
2546 
2547  if (xmlschema)
2548  appendStringInfo(result, "%s\n\n", xmlschema);
2549 
2550  for (i = 0; i < SPI_processed; i++)
2551  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2552  tableforest, targetns, top_level);
2553 
2554  if (!tableforest)
2555  xmldata_root_element_end(result, xmltn);
2556 
2557  SPI_finish();
2558 
2559  return result;
2560 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2485
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
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:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
#define SPI_OK_SELECT
Definition: spi.h:51
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2512
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:3597
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:303
Datum query_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2583 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.

2584 {
2585  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2586  bool nulls = PG_GETARG_BOOL(1);
2587  bool tableforest = PG_GETARG_BOOL(2);
2588  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2589  const char *result;
2590  SPIPlanPtr plan;
2591  Portal portal;
2592 
2593  SPI_connect();
2594 
2595  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2596  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2597 
2598  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2599  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2600 
2602  InvalidOid, nulls,
2603  tableforest, targetns));
2604  SPI_cursor_close(portal);
2605  SPI_finish();
2606 
2608 }
int SPI_connect(void)
Definition: spi.c:84
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:481
int SPI_finish(void)
Definition: spi.c:147
return result
Definition: formatting.c:1618
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1028
#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:2260
#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:3030
TupleDesc tupDesc
Definition: portal.h:154
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:448
#define NULL
Definition: c.h:229
void SPI_cursor_close(Portal portal)
Definition: spi.c:1399
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 2342 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().

2343 {
2344  StringInfoData query;
2345 
2346  initStringInfo(&query);
2347  appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2348  " WHERE relnamespace = %u AND relkind IN ("
2352  " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2353  " ORDER BY relname;", nspid);
2354 
2355  return query_to_oid_list(query.data);
2356 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2317
#define RELKIND_MATVIEW
Definition: pg_class.h:165
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#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 2738 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().

2739 {
2740  Name name = PG_GETARG_NAME(0);
2741  bool nulls = PG_GETARG_BOOL(1);
2742  bool tableforest = PG_GETARG_BOOL(2);
2743  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2744 
2745  char *schemaname;
2746  Oid nspid;
2747 
2748  schemaname = NameStr(*name);
2749  nspid = LookupExplicitNamespace(schemaname, false);
2750 
2752  nulls, tableforest, targetns, true)));
2753 }
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2695
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:441
#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 2842 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().

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  char *schemaname;
2849  Oid nspid;
2850  StringInfo xmlschema;
2851 
2852  schemaname = NameStr(*name);
2853  nspid = LookupExplicitNamespace(schemaname, false);
2854 
2855  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
2856  tableforest, targetns);
2857 
2859  xmlschema->data, nulls,
2860  tableforest, targetns, true)));
2861 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2784
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2695
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:441
#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 2695 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().

2697 {
2699  char *xmlsn;
2700  List *relid_list;
2701  ListCell *cell;
2702 
2704  true, false);
2705  result = makeStringInfo();
2706 
2707  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
2708  appendStringInfoChar(result, '\n');
2709 
2710  if (xmlschema)
2711  appendStringInfo(result, "%s\n\n", xmlschema);
2712 
2713  SPI_connect();
2714 
2715  relid_list = schema_get_xml_visible_tables(nspid);
2716 
2717  foreach(cell, relid_list)
2718  {
2719  Oid relid = lfirst_oid(cell);
2720  StringInfo subres;
2721 
2722  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
2723  targetns, false);
2724 
2725  appendStringInfoString(result, subres->data);
2726  appendStringInfoChar(result, '\n');
2727  }
2728 
2729  SPI_finish();
2730 
2731  xmldata_root_element_end(result, xmlsn);
2732 
2733  return result;
2734 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2485
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2342
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
return result
Definition: formatting.c:1618
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:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
#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:2395
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2512
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

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

2830 {
2831  Name name = PG_GETARG_NAME(0);
2832  bool nulls = PG_GETARG_BOOL(1);
2833  bool tableforest = PG_GETARG_BOOL(2);
2834  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2835 
2837  nulls, tableforest, targetns)));
2838 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2784
#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:441
#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 2784 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().

2786 {
2787  Oid nspid;
2788  List *relid_list;
2789  List *tupdesc_list;
2790  ListCell *cell;
2792 
2793  result = makeStringInfo();
2794 
2795  nspid = LookupExplicitNamespace(schemaname, false);
2796 
2797  xsd_schema_element_start(result, targetns);
2798 
2799  SPI_connect();
2800 
2801  relid_list = schema_get_xml_visible_tables(nspid);
2802 
2803  tupdesc_list = NIL;
2804  foreach(cell, relid_list)
2805  {
2806  Relation rel;
2807 
2808  rel = heap_open(lfirst_oid(cell), AccessShareLock);
2809  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2810  heap_close(rel, NoLock);
2811  }
2812 
2813  appendStringInfoString(result,
2814  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2815 
2816  appendStringInfoString(result,
2817  map_sql_schema_to_xmlschema_types(nspid, relid_list,
2818  nulls, tableforest, targetns));
2819 
2820  xsd_schema_element_end(result);
2821 
2822  SPI_finish();
2823 
2824  return result;
2825 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2760
#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:2743
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2342
int SPI_connect(void)
Definition: spi.c:84
int SPI_finish(void)
Definition: spi.c:147
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1618
#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:189
#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:3368
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2777
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:3133
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 3597 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().

3600 {
3601  int i;
3602  char *xmltn;
3603 
3604  if (tablename)
3605  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3606  else
3607  {
3608  if (tableforest)
3609  xmltn = "row";
3610  else
3611  xmltn = "table";
3612  }
3613 
3614  if (tableforest)
3615  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
3616  else
3617  appendStringInfoString(result, "<row>\n");
3618 
3619  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
3620  {
3621  char *colname;
3622  Datum colval;
3623  bool isnull;
3624 
3626  true, false);
3627  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
3629  i,
3630  &isnull);
3631  if (isnull)
3632  {
3633  if (nulls)
3634  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
3635  }
3636  else
3637  appendStringInfo(result, " <%s>%s</%s>\n",
3638  colname,
3640  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
3641  colname);
3642  }
3643 
3644  if (tableforest)
3645  {
3646  xmldata_root_element_end(result, xmltn);
3647  appendStringInfoChar(result, '\n');
3648  }
3649  else
3650  appendStringInfoString(result, "</row>\n\n");
3651 }
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:891
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2485
SPITupleTable * SPI_tuptable
Definition: spi.c:41
HeapTuple * vals
Definition: spi.h:27
int natts
Definition: tupdesc.h:73
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:781
char * map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:1893
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:835
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
uintptr_t Datum
Definition: postgres.h:372
TupleDesc tupdesc
Definition: spi.h:26
#define NULL
Definition: c.h:229
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2512
int i
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2009
Datum table_to_xml ( PG_FUNCTION_ARGS  )

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

2413 {
2414  Oid relid = PG_GETARG_OID(0);
2415  bool nulls = PG_GETARG_BOOL(1);
2416  bool tableforest = PG_GETARG_BOOL(2);
2417  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2418 
2420  nulls, tableforest,
2421  targetns, true)));
2422 }
#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:2395
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
Datum table_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

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

2639 {
2640  Oid relid = PG_GETARG_OID(0);
2641  bool nulls = PG_GETARG_BOOL(1);
2642  bool tableforest = PG_GETARG_BOOL(2);
2643  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2644  Relation rel;
2645  const char *xmlschema;
2646 
2647  rel = heap_open(relid, AccessShareLock);
2648  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2649  tableforest, targetns);
2650  heap_close(rel, NoLock);
2651 
2653  xmlschema, nulls, tableforest,
2654  targetns, true)));
2655 }
#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:3030
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:2395
char * text_to_cstring(const text *t)
Definition: varlena.c:182
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:441
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 2395 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().

2398 {
2399  StringInfoData query;
2400 
2401  initStringInfo(&query);
2402  appendStringInfo(&query, "SELECT * FROM %s",
2404  ObjectIdGetDatum(relid))));
2405  return query_to_xml_internal(query.data, get_rel_name(relid),
2406  xmlschema, nulls, tableforest,
2407  targetns, top_level);
2408 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define DatumGetCString(X)
Definition: postgres.h:572
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
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:2519
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:1089
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
Datum table_to_xmlschema ( PG_FUNCTION_ARGS  )

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

2565 {
2566  Oid relid = PG_GETARG_OID(0);
2567  bool nulls = PG_GETARG_BOOL(1);
2568  bool tableforest = PG_GETARG_BOOL(2);
2569  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2570  const char *result;
2571  Relation rel;
2572 
2573  rel = heap_open(relid, AccessShareLock);
2574  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2575  tableforest, targetns);
2576  heap_close(rel, NoLock);
2577 
2579 }
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1618
#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:3030
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:448
char * text_to_cstring(const text *t)
Definition: varlena.c:182
Datum texttoxml ( PG_FUNCTION_ARGS  )

Definition at line 590 of file xml.c.

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

591 {
592  text *data = PG_GETARG_TEXT_PP(0);
593 
594  PG_RETURN_XML_P(xmlparse(data, xmloption, true));
595 }
#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:746
static char* unicode_to_sqlchar ( pg_wchar  c)
static

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

1950 {
1951  char utf8string[8]; /* need room for trailing zero */
1952  char *result;
1953 
1954  memset(utf8string, 0, sizeof(utf8string));
1955  unicode_to_utf8(c, (unsigned char *) utf8string);
1956 
1957  result = pg_any_to_server(utf8string, strlen(utf8string), PG_UTF8);
1958  /* if pg_any_to_server didn't strdup, we must */
1959  if (result == utf8string)
1960  result = pstrdup(result);
1961  return result;
1962 }
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:1618
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 252 of file xml.c.

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

253 {
254 #ifdef USE_LIBXML
255  char *s = PG_GETARG_CSTRING(0);
256  xmltype *vardata;
257  xmlDocPtr doc;
258 
259  vardata = (xmltype *) cstring_to_text(s);
260 
261  /*
262  * Parse the data to check if it is well-formed XML data. Assume that
263  * ERROR occurred if parsing failed.
264  */
265  doc = xml_parse(vardata, xmloption, true, GetDatabaseEncoding());
266  xmlFreeDoc(doc);
267 
268  PG_RETURN_XML_P(vardata);
269 #else
270  NO_XML_SUPPORT();
271  return 0;
272 #endif
273 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 882 of file xml.c.

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

Referenced by ExecEvalXmlExpr(), and xmltotext_with_xmloption().

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

Definition at line 4096 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and xmloption.

4097 {
4098 #ifdef USE_LIBXML
4099  text *data = PG_GETARG_TEXT_PP(0);
4100 
4101  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4102 #else
4103  NO_XML_SUPPORT();
4104  return 0;
4105 #endif /* not USE_LIBXML */
4106 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 4122 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_CONTENT.

4123 {
4124 #ifdef USE_LIBXML
4125  text *data = PG_GETARG_TEXT_PP(0);
4126 
4127  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4128 #else
4129  NO_XML_SUPPORT();
4130  return 0;
4131 #endif /* not USE_LIBXML */
4132 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 4109 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.

4110 {
4111 #ifdef USE_LIBXML
4112  text *data = PG_GETARG_TEXT_PP(0);
4113 
4114  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4115 #else
4116  NO_XML_SUPPORT();
4117  return 0;
4118 #endif /* not USE_LIBXML */
4119 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 330 of file xml.c.

References PG_GETARG_XML_P, PG_RETURN_CSTRING, and xml_out_internal().

331 {
332  xmltype *x = PG_GETARG_XML_P(0);
333 
334  /*
335  * xml_out removes the encoding property in all cases. This is because we
336  * cannot control from here whether the datum will be converted to a
337  * different client encoding, so we'd do more harm than good by including
338  * it.
339  */
341 }
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:287
#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 287 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().

288 {
289  char *str = text_to_cstring((text *) x);
290 
291 #ifdef USE_LIBXML
292  size_t len = strlen(str);
293  xmlChar *version;
294  int standalone;
295  int res_code;
296 
297  if ((res_code = parse_xml_decl((xmlChar *) str,
298  &len, &version, NULL, &standalone)) == 0)
299  {
301 
302  initStringInfo(&buf);
303 
304  if (!print_xml_decl(&buf, version, target_encoding, standalone))
305  {
306  /*
307  * If we are not going to produce an XML declaration, eat a single
308  * newline in the original string to prevent empty first lines in
309  * the output.
310  */
311  if (*(str + len) == '\n')
312  len += 1;
313  }
314  appendStringInfoString(&buf, str + len);
315 
316  pfree(str);
317 
318  return buf.data;
319  }
320 
321  xml_ereport_by_code(WARNING, ERRCODE_INTERNAL_ERROR,
322  "could not parse XML declaration in stored value",
323  res_code);
324 #endif
325  return str;
326 }
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define 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 345 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.

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

413 {
414  xmltype *x = PG_GETARG_XML_P(0);
415  char *outval;
417 
418  /*
419  * xml_out_internal doesn't convert the encoding, it just prints the right
420  * declaration. pq_sendtext will do the conversion.
421  */
423 
424  pq_begintypsend(&buf);
425  pq_sendtext(&buf, outval, strlen(outval));
426  pfree(outval);
428 }
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:65
#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:287
Definition: c.h:439
Datum xmlcomment ( PG_FUNCTION_ARGS  )

Definition at line 465 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.

466 {
467 #ifdef USE_LIBXML
468  text *arg = PG_GETARG_TEXT_PP(0);
469  char *argdata = VARDATA_ANY(arg);
470  int len = VARSIZE_ANY_EXHDR(arg);
472  int i;
473 
474  /* check for "--" in string or "-" at the end */
475  for (i = 1; i < len; i++)
476  {
477  if (argdata[i] == '-' && argdata[i - 1] == '-')
478  ereport(ERROR,
479  (errcode(ERRCODE_INVALID_XML_COMMENT),
480  errmsg("invalid XML comment")));
481  }
482  if (len > 0 && argdata[len - 1] == '-')
483  ereport(ERROR,
484  (errcode(ERRCODE_INVALID_XML_COMMENT),
485  errmsg("invalid XML comment")));
486 
487  initStringInfo(&buf);
488  appendStringInfoString(&buf, "<!--");
489  appendStringInfoText(&buf, arg);
490  appendStringInfoString(&buf, "-->");
491 
493 #else
494  NO_XML_SUPPORT();
495  return 0;
496 #endif
497 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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:3651
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
#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:65
#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:441
int i
void * arg
Definition: c.h:439
xmltype* xmlconcat ( List args)

Definition at line 506 of file xml.c.

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

Referenced by ExecEvalXmlExpr(), and xmlconcat2().

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

Definition at line 572 of file xml.c.

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

573 {
574  if (PG_ARGISNULL(0))
575  {
576  if (PG_ARGISNULL(1))
577  PG_RETURN_NULL();
578  else
580  }
581  else if (PG_ARGISNULL(1))
583  else
585  PG_GETARG_XML_P(1))));
586 }
#define list_make2(x1, x2)
Definition: pg_list.h:134
xmltype * xmlconcat(List *args)
Definition: xml.c:506
#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 2512 of file xml.c.

References appendStringInfo().

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

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

Definition at line 2485 of file xml.c.

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

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

2488 {
2489  /* This isn't really wrong but currently makes no sense. */
2490  Assert(top_level || !xmlschema);
2491 
2492  appendStringInfo(result, "<%s", eltname);
2493  if (top_level)
2494  {
2495  appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2496  if (strlen(targetns) > 0)
2497  appendStringInfo(result, " xmlns=\"%s\"", targetns);
2498  }
2499  if (xmlschema)
2500  {
2501  /* FIXME: better targets */
2502  if (strlen(targetns) > 0)
2503  appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2504  else
2505  appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2506  }
2507  appendStringInfoString(result, ">\n");
2508 }
#define NAMESPACE_XSI
Definition: xml.c:223
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
#define Assert(condition)
Definition: c.h:675
xmltype* xmlelement ( XmlExpr xexpr,
Datum named_argvalue,
bool named_argnull,
Datum argvalue,
bool argnull 
)

Definition at line 622 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

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

Definition at line 4023 of file xml.c.

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

4024 {
4025 #ifdef USE_LIBXML
4026  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4027  xmltype *data = PG_GETARG_XML_P(1);
4028  int res_nitems;
4029 
4030  xpath_internal(xpath_expr_text, data, NULL,
4031  &res_nitems, NULL);
4032 
4033  PG_RETURN_BOOL(res_nitems > 0);
4034 #else
4035  NO_XML_SUPPORT();
4036  return 0;
4037 #endif
4038 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 746 of file xml.c.

References GetDatabaseEncoding(), NO_XML_SUPPORT, and NULL.

Referenced by ExecEvalXmlExpr(), and texttoxml().

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

Definition at line 764 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

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

Definition at line 816 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

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

Definition at line 4584 of file xml.c.

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

4585 {
4586 #ifdef USE_LIBXML
4587  XmlTableBuilderData *xtCxt;
4588 
4589  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
4590 
4591  /* Propagate context related error context to libxml2 */
4592  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4593 
4594  if (xtCxt->xpathscomp != NULL)
4595  {
4596  int i;
4597 
4598  for (i = 0; i < xtCxt->natts; i++)
4599  if (xtCxt->xpathscomp[i] != NULL)
4600  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
4601  }
4602 
4603  if (xtCxt->xpathobj != NULL)
4604  xmlXPathFreeObject(xtCxt->xpathobj);
4605  if (xtCxt->xpathcomp != NULL)
4606  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
4607  if (xtCxt->xpathcxt != NULL)
4608  xmlXPathFreeContext(xtCxt->xpathcxt);
4609  if (xtCxt->doc != NULL)
4610  xmlFreeDoc(xtCxt->doc);
4611  if (xtCxt->ctxt != NULL)
4612  xmlFreeParserCtxt(xtCxt->ctxt);
4613 
4614  pg_xml_done(xtCxt->xmlerrcxt, true);
4615 
4616  /* not valid anymore */
4617  xtCxt->magic = 0;
4618  state->opaque = NULL;
4619 
4620 #else
4621  NO_XML_SUPPORT();
4622 #endif /* not USE_LIBXML */
4623 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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 4366 of file xml.c.

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

4367 {
4368 #ifdef USE_LIBXML
4369  XmlTableBuilderData *xtCxt;
4370 
4371  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4372 
4373  /*
4374  * XmlTable returns table - set of composite values. The error context, is
4375  * used for producement more values, between two calls, there can be
4376  * created and used another libxml2 error context. It is libxml2 global
4377  * value, so it should be refreshed any time before any libxml2 usage,
4378  * that is finished by returning some value.
4379  */
4380  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4381 
4382  if (xtCxt->xpathobj == NULL)
4383  {
4384  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4385  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4386  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4387  "could not create XPath object");
4388 
4389  xtCxt->row_count = 0;
4390  }
4391 
4392  if (xtCxt->xpathobj->type == XPATH_NODESET)
4393  {
4394  if (xtCxt->xpathobj->nodesetval != NULL)
4395  {
4396  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4397  return true;
4398  }
4399  }
4400 
4401  return false;
4402 #else
4403  NO_XML_SUPPORT();
4404  return false;
4405 #endif /* not USE_LIBXML */
4406 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 4417 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.

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

4172 {
4173 #ifdef USE_LIBXML
4174  volatile xmlParserCtxtPtr ctxt = NULL;
4175  XmlTableBuilderData *xtCxt;
4176  PgXmlErrorContext *xmlerrcxt;
4177 
4178  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4179  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4180  xtCxt->natts = natts;
4181  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4182 
4183  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4184 
4185  PG_TRY();
4186  {
4187  xmlInitParser();
4188 
4189  ctxt = xmlNewParserCtxt();
4190  if (ctxt == NULL || xmlerrcxt->err_occurred)
4191  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4192  "could not allocate parser context");
4193  }
4194  PG_CATCH();
4195  {
4196  if (ctxt != NULL)
4197  xmlFreeParserCtxt(ctxt);
4198 
4199  pg_xml_done(xmlerrcxt, true);
4200 
4201  PG_RE_THROW();
4202  }
4203  PG_END_TRY();
4204 
4205  xtCxt->xmlerrcxt = xmlerrcxt;
4206  xtCxt->ctxt = ctxt;
4207 
4208  state->opaque = xtCxt;
4209 #else
4210  NO_XML_SUPPORT();
4211 #endif /* not USE_LIBXML */
4212 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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 4334 of file xml.c.

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

4335 {
4336 #ifdef USE_LIBXML
4337  XmlTableBuilderData *xtCxt;
4338  xmlChar *xstr;
4339 
4340  AssertArg(PointerIsValid(path));
4341 
4342  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4343 
4344  if (*path == '\0')
4345  ereport(ERROR,
4346  (errcode(ERRCODE_DATA_EXCEPTION),
4347  errmsg("column path filter must not be empty string")));
4348 
4349  xstr = pg_xmlCharStrndup(path, strlen(path));
4350 
4351  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4352  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4353  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4354  "invalid XPath expression");
4355 #else
4356  NO_XML_SUPPORT();
4357 #endif /* not USE_LIBXML */
4358 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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 4219 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().

4220 {
4221 #ifdef USE_LIBXML
4222  XmlTableBuilderData *xtCxt;
4223  xmltype *xmlval = DatumGetXmlP(value);
4224  char *str;
4225  xmlChar *xstr;
4226  int length;
4227  volatile xmlDocPtr doc = NULL;
4228  volatile xmlXPathContextPtr xpathcxt = NULL;
4229 
4230  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4231 
4232  /*
4233  * Use out function for casting to string (remove encoding property). See
4234  * comment in xml_out.
4235  */
4236  str = xml_out_internal(xmlval, 0);
4237 
4238  length = strlen(str);
4239  xstr = pg_xmlCharStrndup(str, length);
4240 
4241  PG_TRY();
4242  {
4243  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4244  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4245  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4246  "could not parse XML document");
4247  xpathcxt = xmlXPathNewContext(doc);
4248  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4249  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4250  "could not allocate XPath context");
4251  xpathcxt->node = xmlDocGetRootElement(doc);
4252  if (xpathcxt->node == NULL || xtCxt->xmlerrcxt->err_occurred)
4253  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4254  "could not find root XML element");
4255  }
4256  PG_CATCH();
4257  {
4258  if (xpathcxt != NULL)
4259  xmlXPathFreeContext(xpathcxt);
4260  if (doc != NULL)
4261  xmlFreeDoc(doc);
4262 
4263  PG_RE_THROW();
4264  }
4265  PG_END_TRY();
4266 
4267  xtCxt->doc = doc;
4268  xtCxt->xpathcxt = xpathcxt;
4269 #else
4270  NO_XML_SUPPORT();
4271 #endif /* not USE_LIBXML */
4272 }
int length(const List *list)
Definition: list.c:1271
#define NO_XML_SUPPORT()
Definition: xml.c:213
#define DatumGetXmlP(X)
Definition: xml.h:50
static struct @114 value
#define ERROR
Definition: elog.h:43
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:287
#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 4279 of file xml.c.

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

4280 {
4281 #ifdef USE_LIBXML
4282  XmlTableBuilderData *xtCxt;
4283 
4284  if (name == NULL)
4285  ereport(ERROR,
4286  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4287  errmsg("DEFAULT namespace is not supported")));
4288  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4289 
4290  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4291  pg_xmlCharStrndup(name, strlen(name)),
4292  pg_xmlCharStrndup(uri, strlen(uri))))
4293  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4294  "could not set XML namespace");
4295 #else
4296  NO_XML_SUPPORT();
4297 #endif /* not USE_LIBXML */
4298 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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 4305 of file xml.c.

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

4306 {
4307 #ifdef USE_LIBXML
4308  XmlTableBuilderData *xtCxt;
4309  xmlChar *xstr;
4310 
4311  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4312 
4313  if (*path == '\0')
4314  ereport(ERROR,
4315  (errcode(ERRCODE_DATA_EXCEPTION),
4316  errmsg("row path filter must not be empty string")));
4317 
4318  xstr = pg_xmlCharStrndup(path, strlen(path));
4319 
4320  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4321  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4322  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4323  "invalid XPath expression");
4324 #else
4325  NO_XML_SUPPORT();
4326 #endif /* not USE_LIBXML */
4327 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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 599 of file xml.c.

References PG_GETARG_XML_P, and PG_RETURN_TEXT_P.

600 {
601  xmltype *data = PG_GETARG_XML_P(0);
602 
603  /* It's actually binary compatible. */
604  PG_RETURN_TEXT_P((text *) data);
605 }
#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 609 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

610 {
611  if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data))
612  ereport(ERROR,
613  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
614  errmsg("not an XML document")));
615 
616  /* It's actually binary compatible, save for the above check. */
617  return (text *) data;
618 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool xml_is_document(xmltype *arg)
Definition: xml.c:882
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:439
Datum xmlvalidate ( PG_FUNCTION_ARGS  )

Definition at line 872 of file xml.c.

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

873 {
874  ereport(ERROR,
875  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
876  errmsg("xmlvalidate is not implemented")));
877  return 0;
878 }
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 4000 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().

4001 {
4002 #ifdef USE_LIBXML
4003  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4004  xmltype *data = PG_GETARG_XML_P(1);
4005  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4006  ArrayBuildState *astate;
4007 
4008  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4009  xpath_internal(xpath_expr_text, data, namespaces,
4010  NULL, astate);
4012 #else
4013  NO_XML_SUPPORT();
4014  return 0;
4015 #endif
4016 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
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:5055
#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 4046 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.

4047 {
4048 #ifdef USE_LIBXML
4049  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4050  xmltype *data = PG_GETARG_XML_P(1);
4051  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4052  int res_nitems;
4053 
4054  xpath_internal(xpath_expr_text, data, namespaces,
4055  &res_nitems, NULL);
4056 
4057  PG_RETURN_BOOL(res_nitems > 0);
4058 #else
4059  NO_XML_SUPPORT();
4060  return 0;
4061 #endif
4062 }
#define NO_XML_SUPPORT()
Definition: xml.c:213
#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 2777 of file xml.c.

References appendStringInfoString().

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

2778 {
2779  appendStringInfoString(result, "</xsd:schema>");
2780 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static void xsd_schema_element_start ( StringInfo  result,
const char *  targetns 
)
static

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

2761 {
2762  appendStringInfoString(result,
2763  "<xsd:schema\n"
2764  " xmlns:xsd=\"" NAMESPACE_XSD "\"");
2765  if (strlen(targetns) > 0)
2766  appendStringInfo(result,
2767  "\n"
2768  " targetNamespace=\"%s\"\n"
2769  " elementFormDefault=\"qualified\"",
2770  targetns);
2771  appendStringInfoString(result,
2772  ">\n\n");
2773 }
#define NAMESPACE_XSD
Definition: xml.c:222
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189

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:4171
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4366
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4219
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4417
static void XmlTableSetRowFilter(struct TableFuncScanState *state, char *path)
Definition: xml.c:4305
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:4584
static void XmlTableSetNamespace(struct TableFuncScanState *state, char *name, char *uri)
Definition: xml.c:4279
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, char *path, int colnum)
Definition: xml.c:4334

Definition at line 201 of file xml.c.

Referenced by ExecInitTableFuncScan().