PostgreSQL Source Code  git master
xml.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.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/miscnodes.h"
#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xml.h"
Include dependency graph for xml.c:

Go to the source code of this file.

Macros

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

Functions

static void xmldata_root_element_start (StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
 
static void xmldata_root_element_end (StringInfo result, const char *eltname)
 
static StringInfo query_to_xml_internal (const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static const char * map_sql_table_to_xmlschema (TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_schema_to_xmlschema_types (Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_catalog_to_xmlschema_types (List *nspid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_type_to_xml_name (Oid typeoid, int typmod)
 
static const char * map_sql_typecoll_to_xmlschema_types (List *tupdesc_list)
 
static const char * map_sql_type_to_xmlschema_type (Oid typeoid, int typmod)
 
static void SPI_sql_row_to_xmlelement (uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static void XmlTableInitOpaque (struct TableFuncScanState *state, int natts)
 
static void XmlTableSetDocument (struct TableFuncScanState *state, Datum value)
 
static void XmlTableSetNamespace (struct TableFuncScanState *state, const char *name, const char *uri)
 
static void XmlTableSetRowFilter (struct TableFuncScanState *state, const char *path)
 
static void XmlTableSetColumnFilter (struct TableFuncScanState *state, const 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_options (xmltype *data, XmlOptionType xmloption_arg, bool indent)
 
xmltypexmlelement (XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
 
xmltypexmlparse (text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
 
xmltypexmlpi (const 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 (const char *ident, bool fully_escaped, bool escape_period)
 
char * map_xml_name_to_sql_identifier (const char *name)
 
char * map_sql_value_to_xml_value (Datum value, Oid type, bool xml_escape_strings)
 
char * escape_xml (const char *str)
 
static char * _SPI_strdup (const char *s)
 
static Listquery_to_oid_list (const char *query)
 
static Listschema_get_xml_visible_tables (Oid nspid)
 
static Listdatabase_get_xml_visible_schemas (void)
 
static Listdatabase_get_xml_visible_tables (void)
 
static StringInfo table_to_xml_internal (Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum table_to_xml (PG_FUNCTION_ARGS)
 
Datum query_to_xml (PG_FUNCTION_ARGS)
 
Datum cursor_to_xml (PG_FUNCTION_ARGS)
 
Datum table_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum cursor_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum table_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo schema_to_xml_internal (Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum schema_to_xml (PG_FUNCTION_ARGS)
 
static void xsd_schema_element_start (StringInfo result, const char *targetns)
 
static void xsd_schema_element_end (StringInfo result)
 
static StringInfo schema_to_xmlschema_internal (const char *schemaname, bool nulls, bool tableforest, const char *targetns)
 
Datum schema_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum schema_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xml_internal (const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xml (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xmlschema_internal (bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum database_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static char * map_multipart_sql_identifier_to_xml_name (const char *a, const char *b, const char *c, const 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 = XMLBINARY_BASE64
 
int xmloption = XMLOPTION_CONTENT
 
const TableFuncRoutine XmlTableRoutine
 

Macro Definition Documentation

◆ NAMESPACE_SQLXML

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

Definition at line 235 of file xml.c.

◆ NAMESPACE_XSD

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

Definition at line 233 of file xml.c.

◆ NAMESPACE_XSI

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

Definition at line 234 of file xml.c.

◆ NO_XML_SUPPORT

#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.")))
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

Definition at line 225 of file xml.c.

◆ PG_XML_DEFAULT_VERSION

#define PG_XML_DEFAULT_VERSION   "1.0"

Definition at line 291 of file xml.c.

◆ XML_VISIBLE_SCHEMAS

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

◆ XML_VISIBLE_SCHEMAS_EXCLUDE

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

Definition at line 2742 of file xml.c.

Function Documentation

◆ _SPI_strdup()

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2635 of file xml.c.

2636 {
2637  size_t len = strlen(s) + 1;
2638  char *ret = SPI_palloc(len);
2639 
2640  memcpy(ret, s, len);
2641  return ret;
2642 }
const void size_t len
void * SPI_palloc(Size size)
Definition: spi.c:1336

References len, and SPI_palloc().

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

◆ cstring_to_xmltype()

static xmltype* cstring_to_xmltype ( const char *  string)
static

Definition at line 464 of file xml.c.

465 {
466  return (xmltype *) cstring_to_text(string);
467 }
Definition: c.h:676
text * cstring_to_text(const char *s)
Definition: varlena.c:182

References cstring_to_text().

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

◆ cursor_to_xml()

Datum cursor_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2819 of file xml.c.

2820 {
2822  int32 count = PG_GETARG_INT32(1);
2823  bool nulls = PG_GETARG_BOOL(2);
2824  bool tableforest = PG_GETARG_BOOL(3);
2825  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2826 
2827  StringInfoData result;
2828  Portal portal;
2829  uint64 i;
2830 
2831  initStringInfo(&result);
2832 
2833  if (!tableforest)
2834  {
2835  xmldata_root_element_start(&result, "table", NULL, targetns, true);
2836  appendStringInfoChar(&result, '\n');
2837  }
2838 
2839  SPI_connect();
2840  portal = SPI_cursor_find(name);
2841  if (portal == NULL)
2842  ereport(ERROR,
2843  (errcode(ERRCODE_UNDEFINED_CURSOR),
2844  errmsg("cursor \"%s\" does not exist", name)));
2845 
2846  SPI_cursor_fetch(portal, true, count);
2847  for (i = 0; i < SPI_processed; i++)
2848  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2849  tableforest, targetns, true);
2850 
2851  SPI_finish();
2852 
2853  if (!tableforest)
2854  xmldata_root_element_end(&result, "table");
2855 
2857 }
signed int int32
Definition: c.h:483
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
int i
Definition: isn.c:73
uint64 SPI_processed
Definition: spi.c:45
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1792
int SPI_connect(void)
Definition: spi.c:95
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1804
int SPI_finish(void)
Definition: spi.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * text_to_cstring(const text *t)
Definition: varlena.c:215
const char * name
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:457
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2873
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2900
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:3992
#define PG_RETURN_XML_P(x)
Definition: xml.h:63

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

◆ cursor_to_xmlschema()

Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3000 of file xml.c.

3001 {
3003  bool nulls = PG_GETARG_BOOL(1);
3004  bool tableforest = PG_GETARG_BOOL(2);
3005  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3006  const char *xmlschema;
3007  Portal portal;
3008 
3009  SPI_connect();
3010  portal = SPI_cursor_find(name);
3011  if (portal == NULL)
3012  ereport(ERROR,
3013  (errcode(ERRCODE_UNDEFINED_CURSOR),
3014  errmsg("cursor \"%s\" does not exist", name)));
3015  if (portal->tupDesc == NULL)
3016  ereport(ERROR,
3017  (errcode(ERRCODE_INVALID_CURSOR_STATE),
3018  errmsg("portal \"%s\" does not return tuples", name)));
3019 
3020  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
3021  InvalidOid, nulls,
3022  tableforest, targetns));
3023  SPI_finish();
3024 
3025  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
3026 }
#define InvalidOid
Definition: postgres_ext.h:36
TupleDesc tupDesc
Definition: portal.h:160
static char * _SPI_strdup(const char *s)
Definition: xml.c:2635
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:464
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3422

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

◆ database_get_xml_visible_schemas()

static List* database_get_xml_visible_schemas ( void  )
static

Definition at line 2748 of file xml.c.

2749 {
2750  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2751 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2692
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2744

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

◆ database_get_xml_visible_tables()

static List* database_get_xml_visible_tables ( void  )
static

Definition at line 2755 of file xml.c.

2756 {
2757  /* At the moment there is no order required here. */
2758  return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2759  " WHERE relkind IN ("
2760  CppAsString2(RELKIND_RELATION) ","
2761  CppAsString2(RELKIND_MATVIEW) ","
2762  CppAsString2(RELKIND_VIEW) ")"
2763  " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2764  " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2765 }
#define CppAsString2(x)
Definition: c.h:316

References CppAsString2, query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xmlschema_internal().

◆ database_to_xml()

Datum database_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 3305 of file xml.c.

3306 {
3307  bool nulls = PG_GETARG_BOOL(0);
3308  bool tableforest = PG_GETARG_BOOL(1);
3309  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3310 
3312  tableforest, targetns)));
3313 }
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3262

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

◆ database_to_xml_and_xmlschema()

Datum database_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3372 of file xml.c.

3373 {
3374  bool nulls = PG_GETARG_BOOL(0);
3375  bool tableforest = PG_GETARG_BOOL(1);
3376  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3377  StringInfo xmlschema;
3378 
3379  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3380 
3382  nulls, tableforest, targetns)));
3383 }
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3317

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().

◆ database_to_xml_internal()

static StringInfo database_to_xml_internal ( const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3262 of file xml.c.

3264 {
3265  StringInfo result;
3266  List *nspid_list;
3267  ListCell *cell;
3268  char *xmlcn;
3269 
3271  true, false);
3272  result = makeStringInfo();
3273 
3274  xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
3275  appendStringInfoChar(result, '\n');
3276 
3277  if (xmlschema)
3278  appendStringInfo(result, "%s\n\n", xmlschema);
3279 
3280  SPI_connect();
3281 
3282  nspid_list = database_get_xml_visible_schemas();
3283 
3284  foreach(cell, nspid_list)
3285  {
3286  Oid nspid = lfirst_oid(cell);
3287  StringInfo subres;
3288 
3289  subres = schema_to_xml_internal(nspid, NULL, nulls,
3290  tableforest, targetns, false);
3291 
3292  appendBinaryStringInfo(result, subres->data, subres->len);
3293  appendStringInfoChar(result, '\n');
3294  }
3295 
3296  SPI_finish();
3297 
3298  xmldata_root_element_end(result, xmlcn);
3299 
3300  return result;
3301 }
int nspid
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3084
Oid MyDatabaseId
Definition: globals.c:89
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:31
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:227
Definition: pg_list.h:54
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2286
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3087
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2748

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), StringInfoData::data, database_get_xml_visible_schemas(), get_database_name(), StringInfoData::len, lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), MyDatabaseId, nspid, 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().

◆ database_to_xmlschema()

Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3360 of file xml.c.

3361 {
3362  bool nulls = PG_GETARG_BOOL(0);
3363  bool tableforest = PG_GETARG_BOOL(1);
3364  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3365 
3367  tableforest, targetns)));
3368 }

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

◆ database_to_xmlschema_internal()

static StringInfo database_to_xmlschema_internal ( bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3317 of file xml.c.

3319 {
3320  List *relid_list;
3321  List *nspid_list;
3322  List *tupdesc_list;
3323  ListCell *cell;
3324  StringInfo result;
3325 
3326  result = makeStringInfo();
3327 
3328  xsd_schema_element_start(result, targetns);
3329 
3330  SPI_connect();
3331 
3332  relid_list = database_get_xml_visible_tables();
3333  nspid_list = database_get_xml_visible_schemas();
3334 
3335  tupdesc_list = NIL;
3336  foreach(cell, relid_list)
3337  {
3338  Relation rel;
3339 
3340  rel = table_open(lfirst_oid(cell), AccessShareLock);
3341  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3342  table_close(rel, NoLock);
3343  }
3344 
3345  appendStringInfoString(result,
3346  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3347 
3348  appendStringInfoString(result,
3349  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3350 
3351  xsd_schema_element_end(result);
3352 
3353  SPI_finish();
3354 
3355  return result;
3356 }
List * lappend(List *list, void *datum)
Definition: list.c:338
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
#define NIL
Definition: pg_list.h:68
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
TupleDesc rd_att
Definition: rel.h:112
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:111
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2755
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3600
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:3152
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3762
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:3169

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

Referenced by database_to_xml_and_xmlschema(), and database_to_xmlschema().

◆ escape_xml()

char* escape_xml ( const char *  str)

Definition at line 2603 of file xml.c.

2604 {
2606  const char *p;
2607 
2608  initStringInfo(&buf);
2609  for (p = str; *p; p++)
2610  {
2611  switch (*p)
2612  {
2613  case '&':
2614  appendStringInfoString(&buf, "&amp;");
2615  break;
2616  case '<':
2617  appendStringInfoString(&buf, "&lt;");
2618  break;
2619  case '>':
2620  appendStringInfoString(&buf, "&gt;");
2621  break;
2622  case '\r':
2623  appendStringInfoString(&buf, "&#x0d;");
2624  break;
2625  default:
2627  break;
2628  }
2629  }
2630  return buf.data;
2631 }
static char * buf
Definition: pg_test_fsync.c:67
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128

References appendStringInfoCharMacro, appendStringInfoString(), buf, initStringInfo(), and generate_unaccent_rules::str.

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

◆ map_multipart_sql_identifier_to_xml_name()

static char* map_multipart_sql_identifier_to_xml_name ( const char *  a,
const char *  b,
const char *  c,
const char *  d 
)
static

Definition at line 3391 of file xml.c.

3392 {
3393  StringInfoData result;
3394 
3395  initStringInfo(&result);
3396 
3397  if (a)
3398  appendStringInfoString(&result,
3399  map_sql_identifier_to_xml_name(a, true, true));
3400  if (b)
3401  appendStringInfo(&result, ".%s",
3402  map_sql_identifier_to_xml_name(b, true, true));
3403  if (c)
3404  appendStringInfo(&result, ".%s",
3405  map_sql_identifier_to_xml_name(c, true, true));
3406  if (d)
3407  appendStringInfo(&result, ".%s",
3408  map_sql_identifier_to_xml_name(d, true, true));
3409 
3410  return result.data;
3411 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69
char * c

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

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().

◆ map_sql_catalog_to_xmlschema_types()

static const char * map_sql_catalog_to_xmlschema_types ( List nspid_list,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3600 of file xml.c.

3602 {
3603  char *dbname;
3604  char *xmlcn;
3605  char *catalogtypename;
3606  StringInfoData result;
3607  ListCell *cell;
3608 
3610 
3611  initStringInfo(&result);
3612 
3613  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3614 
3615  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3616  dbname,
3617  NULL,
3618  NULL);
3619 
3620  appendStringInfo(&result,
3621  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3622  appendStringInfoString(&result,
3623  " <xsd:all>\n");
3624 
3625  foreach(cell, nspid_list)
3626  {
3627  Oid nspid = lfirst_oid(cell);
3628  char *nspname = get_namespace_name(nspid);
3629  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3630  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3631  dbname,
3632  nspname,
3633  NULL);
3634 
3635  appendStringInfo(&result,
3636  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3637  xmlsn, schematypename);
3638  }
3639 
3640  appendStringInfoString(&result,
3641  " </xsd:all>\n");
3642  appendStringInfoString(&result,
3643  "</xsd:complexType>\n\n");
3644 
3645  appendStringInfo(&result,
3646  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3647  xmlcn, catalogtypename);
3648 
3649  return result.data;
3650 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3348
char * dbname
Definition: streamutil.c:51
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3391

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, and nspid.

Referenced by database_to_xmlschema_internal().

◆ map_sql_identifier_to_xml_name()

char* map_sql_identifier_to_xml_name ( const char *  ident,
bool  fully_escaped,
bool  escape_period 
)

Definition at line 2286 of file xml.c.

2288 {
2289 #ifdef USE_LIBXML
2291  const char *p;
2292 
2293  /*
2294  * SQL/XML doesn't make use of this case anywhere, so it's probably a
2295  * mistake.
2296  */
2297  Assert(fully_escaped || !escape_period);
2298 
2299  initStringInfo(&buf);
2300 
2301  for (p = ident; *p; p += pg_mblen(p))
2302  {
2303  if (*p == ':' && (p == ident || fully_escaped))
2304  appendStringInfoString(&buf, "_x003A_");
2305  else if (*p == '_' && *(p + 1) == 'x')
2306  appendStringInfoString(&buf, "_x005F_");
2307  else if (fully_escaped && p == ident &&
2308  pg_strncasecmp(p, "xml", 3) == 0)
2309  {
2310  if (*p == 'x')
2311  appendStringInfoString(&buf, "_x0078_");
2312  else
2313  appendStringInfoString(&buf, "_x0058_");
2314  }
2315  else if (escape_period && *p == '.')
2316  appendStringInfoString(&buf, "_x002E_");
2317  else
2318  {
2319  pg_wchar u = sqlchar_to_unicode(p);
2320 
2321  if ((p == ident)
2322  ? !is_valid_xml_namefirst(u)
2323  : !is_valid_xml_namechar(u))
2324  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
2325  else
2327  }
2328  }
2329 
2330  return buf.data;
2331 #else /* not USE_LIBXML */
2332  NO_XML_SUPPORT();
2333  return NULL;
2334 #endif /* not USE_LIBXML */
2335 }
#define ident
Definition: indent_codes.h:47
Assert(fmt[strlen(fmt) - 1] !='\n')
unsigned int pg_wchar
Definition: mbprint.c:31
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1024
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define NO_XML_SUPPORT()
Definition: xml.c:225

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert(), buf, ident, initStringInfo(), NO_XML_SUPPORT, 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().

◆ map_sql_schema_to_xmlschema_types()

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

3529 {
3530  char *dbname;
3531  char *nspname;
3532  char *xmlsn;
3533  char *schematypename;
3534  StringInfoData result;
3535  ListCell *cell;
3536 
3538  nspname = get_namespace_name(nspid);
3539 
3540  initStringInfo(&result);
3541 
3542  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3543 
3544  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3545  dbname,
3546  nspname,
3547  NULL);
3548 
3549  appendStringInfo(&result,
3550  "<xsd:complexType name=\"%s\">\n", schematypename);
3551  if (!tableforest)
3552  appendStringInfoString(&result,
3553  " <xsd:all>\n");
3554  else
3555  appendStringInfoString(&result,
3556  " <xsd:sequence>\n");
3557 
3558  foreach(cell, relid_list)
3559  {
3560  Oid relid = lfirst_oid(cell);
3561  char *relname = get_rel_name(relid);
3562  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3563  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3564  dbname,
3565  nspname,
3566  relname);
3567 
3568  if (!tableforest)
3569  appendStringInfo(&result,
3570  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3571  xmltn, tabletypename);
3572  else
3573  appendStringInfo(&result,
3574  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3575  xmltn, tabletypename);
3576  }
3577 
3578  if (!tableforest)
3579  appendStringInfoString(&result,
3580  " </xsd:all>\n");
3581  else
3582  appendStringInfoString(&result,
3583  " </xsd:sequence>\n");
3584  appendStringInfoString(&result,
3585  "</xsd:complexType>\n\n");
3586 
3587  appendStringInfo(&result,
3588  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3589  xmlsn, schematypename);
3590 
3591  return result.data;
3592 }
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1932
NameData relname
Definition: pg_class.h:38

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, nspid, and relname.

Referenced by schema_to_xmlschema_internal().

◆ map_sql_table_to_xmlschema()

static const char * map_sql_table_to_xmlschema ( TupleDesc  tupdesc,
Oid  relid,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3422 of file xml.c.

3424 {
3425  int i;
3426  char *xmltn;
3427  char *tabletypename;
3428  char *rowtypename;
3429  StringInfoData result;
3430 
3431  initStringInfo(&result);
3432 
3433  if (OidIsValid(relid))
3434  {
3435  HeapTuple tuple;
3436  Form_pg_class reltuple;
3437 
3438  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3439  if (!HeapTupleIsValid(tuple))
3440  elog(ERROR, "cache lookup failed for relation %u", relid);
3441  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3442 
3443  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3444  true, false);
3445 
3446  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3448  get_namespace_name(reltuple->relnamespace),
3449  NameStr(reltuple->relname));
3450 
3451  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3453  get_namespace_name(reltuple->relnamespace),
3454  NameStr(reltuple->relname));
3455 
3456  ReleaseSysCache(tuple);
3457  }
3458  else
3459  {
3460  if (tableforest)
3461  xmltn = "row";
3462  else
3463  xmltn = "table";
3464 
3465  tabletypename = "TableType";
3466  rowtypename = "RowType";
3467  }
3468 
3469  xsd_schema_element_start(&result, targetns);
3470 
3471  appendStringInfoString(&result,
3473 
3474  appendStringInfo(&result,
3475  "<xsd:complexType name=\"%s\">\n"
3476  " <xsd:sequence>\n",
3477  rowtypename);
3478 
3479  for (i = 0; i < tupdesc->natts; i++)
3480  {
3481  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3482 
3483  if (att->attisdropped)
3484  continue;
3485  appendStringInfo(&result,
3486  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3488  true, false),
3489  map_sql_type_to_xml_name(att->atttypid, -1),
3490  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3491  }
3492 
3493  appendStringInfoString(&result,
3494  " </xsd:sequence>\n"
3495  "</xsd:complexType>\n\n");
3496 
3497  if (!tableforest)
3498  {
3499  appendStringInfo(&result,
3500  "<xsd:complexType name=\"%s\">\n"
3501  " <xsd:sequence>\n"
3502  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3503  " </xsd:sequence>\n"
3504  "</xsd:complexType>\n\n",
3505  tabletypename, rowtypename);
3506 
3507  appendStringInfo(&result,
3508  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3509  xmltn, tabletypename);
3510  }
3511  else
3512  appendStringInfo(&result,
3513  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3514  xmltn, rowtypename);
3515 
3516  xsd_schema_element_end(&result);
3517 
3518  return result.data;
3519 }
#define NameStr(name)
Definition: c.h:735
#define OidIsValid(objectId)
Definition: c.h:764
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define list_make1(x1)
Definition: pg_list.h:212
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
@ RELOID
Definition: syscache.h:89
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3657

References appendStringInfo(), appendStringInfoString(), 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, TupleDescData::natts, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), RELOID, SearchSysCache1(), TupleDescAttr, 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().

◆ map_sql_type_to_xml_name()

static const char * map_sql_type_to_xml_name ( Oid  typeoid,
int  typmod 
)
static

Definition at line 3657 of file xml.c.

3658 {
3659  StringInfoData result;
3660 
3661  initStringInfo(&result);
3662 
3663  switch (typeoid)
3664  {
3665  case BPCHAROID:
3666  if (typmod == -1)
3667  appendStringInfoString(&result, "CHAR");
3668  else
3669  appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3670  break;
3671  case VARCHAROID:
3672  if (typmod == -1)
3673  appendStringInfoString(&result, "VARCHAR");
3674  else
3675  appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3676  break;
3677  case NUMERICOID:
3678  if (typmod == -1)
3679  appendStringInfoString(&result, "NUMERIC");
3680  else
3681  appendStringInfo(&result, "NUMERIC_%d_%d",
3682  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3683  (typmod - VARHDRSZ) & 0xffff);
3684  break;
3685  case INT4OID:
3686  appendStringInfoString(&result, "INTEGER");
3687  break;
3688  case INT2OID:
3689  appendStringInfoString(&result, "SMALLINT");
3690  break;
3691  case INT8OID:
3692  appendStringInfoString(&result, "BIGINT");
3693  break;
3694  case FLOAT4OID:
3695  appendStringInfoString(&result, "REAL");
3696  break;
3697  case FLOAT8OID:
3698  appendStringInfoString(&result, "DOUBLE");
3699  break;
3700  case BOOLOID:
3701  appendStringInfoString(&result, "BOOLEAN");
3702  break;
3703  case TIMEOID:
3704  if (typmod == -1)
3705  appendStringInfoString(&result, "TIME");
3706  else
3707  appendStringInfo(&result, "TIME_%d", typmod);
3708  break;
3709  case TIMETZOID:
3710  if (typmod == -1)
3711  appendStringInfoString(&result, "TIME_WTZ");
3712  else
3713  appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3714  break;
3715  case TIMESTAMPOID:
3716  if (typmod == -1)
3717  appendStringInfoString(&result, "TIMESTAMP");
3718  else
3719  appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3720  break;
3721  case TIMESTAMPTZOID:
3722  if (typmod == -1)
3723  appendStringInfoString(&result, "TIMESTAMP_WTZ");
3724  else
3725  appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3726  break;
3727  case DATEOID:
3728  appendStringInfoString(&result, "DATE");
3729  break;
3730  case XMLOID:
3731  appendStringInfoString(&result, "XML");
3732  break;
3733  default:
3734  {
3735  HeapTuple tuple;
3736  Form_pg_type typtuple;
3737 
3738  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3739  if (!HeapTupleIsValid(tuple))
3740  elog(ERROR, "cache lookup failed for type %u", typeoid);
3741  typtuple = (Form_pg_type) GETSTRUCT(tuple);
3742 
3743  appendStringInfoString(&result,
3744  map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3746  get_namespace_name(typtuple->typnamespace),
3747  NameStr(typtuple->typname)));
3748 
3749  ReleaseSysCache(tuple);
3750  }
3751  }
3752 
3753  return result.data;
3754 }
#define VARHDRSZ
Definition: c.h:681
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
@ TYPEOID
Definition: syscache.h:114

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, elog(), ERROR, get_database_name(), get_namespace_name(), GETSTRUCT, HeapTupleIsValid, initStringInfo(), map_multipart_sql_identifier_to_xml_name(), MyDatabaseId, NameStr, ObjectIdGetDatum(), ReleaseSysCache(), SearchSysCache1(), TYPEOID, and VARHDRSZ.

Referenced by map_sql_table_to_xmlschema(), and map_sql_type_to_xmlschema_type().

◆ map_sql_type_to_xmlschema_type()

static const char * map_sql_type_to_xmlschema_type ( Oid  typeoid,
int  typmod 
)
static

Definition at line 3817 of file xml.c.

3818 {
3819  StringInfoData result;
3820  const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3821 
3822  initStringInfo(&result);
3823 
3824  if (typeoid == XMLOID)
3825  {
3826  appendStringInfoString(&result,
3827  "<xsd:complexType mixed=\"true\">\n"
3828  " <xsd:sequence>\n"
3829  " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3830  " </xsd:sequence>\n"
3831  "</xsd:complexType>\n");
3832  }
3833  else
3834  {
3835  appendStringInfo(&result,
3836  "<xsd:simpleType name=\"%s\">\n", typename);
3837 
3838  switch (typeoid)
3839  {
3840  case BPCHAROID:
3841  case VARCHAROID:
3842  case TEXTOID:
3843  appendStringInfoString(&result,
3844  " <xsd:restriction base=\"xsd:string\">\n");
3845  if (typmod != -1)
3846  appendStringInfo(&result,
3847  " <xsd:maxLength value=\"%d\"/>\n",
3848  typmod - VARHDRSZ);
3849  appendStringInfoString(&result, " </xsd:restriction>\n");
3850  break;
3851 
3852  case BYTEAOID:
3853  appendStringInfo(&result,
3854  " <xsd:restriction base=\"xsd:%s\">\n"
3855  " </xsd:restriction>\n",
3856  xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3857  break;
3858 
3859  case NUMERICOID:
3860  if (typmod != -1)
3861  appendStringInfo(&result,
3862  " <xsd:restriction base=\"xsd:decimal\">\n"
3863  " <xsd:totalDigits value=\"%d\"/>\n"
3864  " <xsd:fractionDigits value=\"%d\"/>\n"
3865  " </xsd:restriction>\n",
3866  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3867  (typmod - VARHDRSZ) & 0xffff);
3868  break;
3869 
3870  case INT2OID:
3871  appendStringInfo(&result,
3872  " <xsd:restriction base=\"xsd:short\">\n"
3873  " <xsd:maxInclusive value=\"%d\"/>\n"
3874  " <xsd:minInclusive value=\"%d\"/>\n"
3875  " </xsd:restriction>\n",
3876  SHRT_MAX, SHRT_MIN);
3877  break;
3878 
3879  case INT4OID:
3880  appendStringInfo(&result,
3881  " <xsd:restriction base=\"xsd:int\">\n"
3882  " <xsd:maxInclusive value=\"%d\"/>\n"
3883  " <xsd:minInclusive value=\"%d\"/>\n"
3884  " </xsd:restriction>\n",
3885  INT_MAX, INT_MIN);
3886  break;
3887 
3888  case INT8OID:
3889  appendStringInfo(&result,
3890  " <xsd:restriction base=\"xsd:long\">\n"
3891  " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3892  " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3893  " </xsd:restriction>\n",
3894  PG_INT64_MAX,
3895  PG_INT64_MIN);
3896  break;
3897 
3898  case FLOAT4OID:
3899  appendStringInfoString(&result,
3900  " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3901  break;
3902 
3903  case FLOAT8OID:
3904  appendStringInfoString(&result,
3905  " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3906  break;
3907 
3908  case BOOLOID:
3909  appendStringInfoString(&result,
3910  " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
3911  break;
3912 
3913  case TIMEOID:
3914  case TIMETZOID:
3915  {
3916  const char *tz = (typeoid == TIMETZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3917 
3918  if (typmod == -1)
3919  appendStringInfo(&result,
3920  " <xsd:restriction base=\"xsd:time\">\n"
3921  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3922  " </xsd:restriction>\n", tz);
3923  else if (typmod == 0)
3924  appendStringInfo(&result,
3925  " <xsd:restriction base=\"xsd:time\">\n"
3926  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3927  " </xsd:restriction>\n", tz);
3928  else
3929  appendStringInfo(&result,
3930  " <xsd:restriction base=\"xsd:time\">\n"
3931  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3932  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3933  break;
3934  }
3935 
3936  case TIMESTAMPOID:
3937  case TIMESTAMPTZOID:
3938  {
3939  const char *tz = (typeoid == TIMESTAMPTZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3940 
3941  if (typmod == -1)
3942  appendStringInfo(&result,
3943  " <xsd:restriction base=\"xsd:dateTime\">\n"
3944  " <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"
3945  " </xsd:restriction>\n", tz);
3946  else if (typmod == 0)
3947  appendStringInfo(&result,
3948  " <xsd:restriction base=\"xsd:dateTime\">\n"
3949  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3950  " </xsd:restriction>\n", tz);
3951  else
3952  appendStringInfo(&result,
3953  " <xsd:restriction base=\"xsd:dateTime\">\n"
3954  " <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"
3955  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3956  break;
3957  }
3958 
3959  case DATEOID:
3960  appendStringInfoString(&result,
3961  " <xsd:restriction base=\"xsd:date\">\n"
3962  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
3963  " </xsd:restriction>\n");
3964  break;
3965 
3966  default:
3967  if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
3968  {
3969  Oid base_typeoid;
3970  int32 base_typmod = -1;
3971 
3972  base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
3973 
3974  appendStringInfo(&result,
3975  " <xsd:restriction base=\"%s\"/>\n",
3976  map_sql_type_to_xml_name(base_typeoid, base_typmod));
3977  }
3978  break;
3979  }
3980  appendStringInfoString(&result, "</xsd:simpleType>\n");
3981  }
3982 
3983  return result.data;
3984 }
#define INT64_FORMAT
Definition: c.h:537
#define PG_INT64_MAX
Definition: c.h:581
#define PG_INT64_MIN
Definition: c.h:580
char get_typtype(Oid typid)
Definition: lsyscache.c:2611
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2520
int xmlbinary
Definition: xml.c:99
@ XMLBINARY_BASE64
Definition: xml.h:35

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, get_typtype(), getBaseTypeAndTypmod(), initStringInfo(), INT64_FORMAT, map_sql_type_to_xml_name(), PG_INT64_MAX, PG_INT64_MIN, VARHDRSZ, xmlbinary, and XMLBINARY_BASE64.

Referenced by map_sql_typecoll_to_xmlschema_types().

◆ map_sql_typecoll_to_xmlschema_types()

static const char * map_sql_typecoll_to_xmlschema_types ( List tupdesc_list)
static

Definition at line 3762 of file xml.c.

3763 {
3764  List *uniquetypes = NIL;
3765  int i;
3766  StringInfoData result;
3767  ListCell *cell0;
3768 
3769  /* extract all column types used in the set of TupleDescs */
3770  foreach(cell0, tupdesc_list)
3771  {
3772  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3773 
3774  for (i = 0; i < tupdesc->natts; i++)
3775  {
3776  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3777 
3778  if (att->attisdropped)
3779  continue;
3780  uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3781  }
3782  }
3783 
3784  /* add base types of domains */
3785  foreach(cell0, uniquetypes)
3786  {
3787  Oid typid = lfirst_oid(cell0);
3788  Oid basetypid = getBaseType(typid);
3789 
3790  if (basetypid != typid)
3791  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3792  }
3793 
3794  /* Convert to textual form */
3795  initStringInfo(&result);
3796 
3797  foreach(cell0, uniquetypes)
3798  {
3799  appendStringInfo(&result, "%s\n",
3801  -1));
3802  }
3803 
3804  return result.data;
3805 }
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1379
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2503
#define lfirst(lc)
Definition: pg_list.h:172
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3817

References appendStringInfo(), StringInfoData::data, getBaseType(), i, initStringInfo(), lfirst, lfirst_oid, list_append_unique_oid(), map_sql_type_to_xmlschema_type(), TupleDescData::natts, NIL, and TupleDescAttr.

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

◆ map_sql_value_to_xml_value()

char* map_sql_value_to_xml_value ( Datum  value,
Oid  type,
bool  xml_escape_strings 
)

Definition at line 2384 of file xml.c.

2385 {
2387  {
2388  ArrayType *array;
2389  Oid elmtype;
2390  int16 elmlen;
2391  bool elmbyval;
2392  char elmalign;
2393  int num_elems;
2394  Datum *elem_values;
2395  bool *elem_nulls;
2397  int i;
2398 
2399  array = DatumGetArrayTypeP(value);
2400  elmtype = ARR_ELEMTYPE(array);
2401  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2402 
2403  deconstruct_array(array, elmtype,
2404  elmlen, elmbyval, elmalign,
2405  &elem_values, &elem_nulls,
2406  &num_elems);
2407 
2408  initStringInfo(&buf);
2409 
2410  for (i = 0; i < num_elems; i++)
2411  {
2412  if (elem_nulls[i])
2413  continue;
2414  appendStringInfoString(&buf, "<element>");
2416  map_sql_value_to_xml_value(elem_values[i],
2417  elmtype, true));
2418  appendStringInfoString(&buf, "</element>");
2419  }
2420 
2421  pfree(elem_values);
2422  pfree(elem_nulls);
2423 
2424  return buf.data;
2425  }
2426  else
2427  {
2428  Oid typeOut;
2429  bool isvarlena;
2430  char *str;
2431 
2432  /*
2433  * Flatten domains; the special-case treatments below should apply to,
2434  * eg, domains over boolean not just boolean.
2435  */
2436  type = getBaseType(type);
2437 
2438  /*
2439  * Special XSD formatting for some data types
2440  */
2441  switch (type)
2442  {
2443  case BOOLOID:
2444  if (DatumGetBool(value))
2445  return "true";
2446  else
2447  return "false";
2448 
2449  case DATEOID:
2450  {
2451  DateADT date;
2452  struct pg_tm tm;
2453  char buf[MAXDATELEN + 1];
2454 
2456  /* XSD doesn't support infinite values */
2457  if (DATE_NOT_FINITE(date))
2458  ereport(ERROR,
2459  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2460  errmsg("date out of range"),
2461  errdetail("XML does not support infinite date values.")));
2463  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2465 
2466  return pstrdup(buf);
2467  }
2468 
2469  case TIMESTAMPOID:
2470  {
2472  struct pg_tm tm;
2473  fsec_t fsec;
2474  char buf[MAXDATELEN + 1];
2475 
2477 
2478  /* XSD doesn't support infinite values */
2480  ereport(ERROR,
2481  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2482  errmsg("timestamp out of range"),
2483  errdetail("XML does not support infinite timestamp values.")));
2484  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2485  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2486  else
2487  ereport(ERROR,
2488  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2489  errmsg("timestamp out of range")));
2490 
2491  return pstrdup(buf);
2492  }
2493 
2494  case TIMESTAMPTZOID:
2495  {
2497  struct pg_tm tm;
2498  int tz;
2499  fsec_t fsec;
2500  const char *tzn = NULL;
2501  char buf[MAXDATELEN + 1];
2502 
2504 
2505  /* XSD doesn't support infinite values */
2507  ereport(ERROR,
2508  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2509  errmsg("timestamp out of range"),
2510  errdetail("XML does not support infinite timestamp values.")));
2511  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2512  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2513  else
2514  ereport(ERROR,
2515  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2516  errmsg("timestamp out of range")));
2517 
2518  return pstrdup(buf);
2519  }
2520 
2521 #ifdef USE_LIBXML
2522  case BYTEAOID:
2523  {
2524  bytea *bstr = DatumGetByteaPP(value);
2525  PgXmlErrorContext *xmlerrcxt;
2526  volatile xmlBufferPtr buf = NULL;
2527  volatile xmlTextWriterPtr writer = NULL;
2528  char *result;
2529 
2530  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2531 
2532  PG_TRY();
2533  {
2534  buf = xmlBufferCreate();
2535  if (buf == NULL || xmlerrcxt->err_occurred)
2536  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2537  "could not allocate xmlBuffer");
2538  writer = xmlNewTextWriterMemory(buf, 0);
2539  if (writer == NULL || xmlerrcxt->err_occurred)
2540  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2541  "could not allocate xmlTextWriter");
2542 
2543  if (xmlbinary == XMLBINARY_BASE64)
2544  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2545  0, VARSIZE_ANY_EXHDR(bstr));
2546  else
2547  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2548  0, VARSIZE_ANY_EXHDR(bstr));
2549 
2550  /* we MUST do this now to flush data out to the buffer */
2551  xmlFreeTextWriter(writer);
2552  writer = NULL;
2553 
2554  result = pstrdup((const char *) xmlBufferContent(buf));
2555  }
2556  PG_CATCH();
2557  {
2558  if (writer)
2559  xmlFreeTextWriter(writer);
2560  if (buf)
2561  xmlBufferFree(buf);
2562 
2563  pg_xml_done(xmlerrcxt, true);
2564 
2565  PG_RE_THROW();
2566  }
2567  PG_END_TRY();
2568 
2569  xmlBufferFree(buf);
2570 
2571  pg_xml_done(xmlerrcxt, false);
2572 
2573  return result;
2574  }
2575 #endif /* USE_LIBXML */
2576 
2577  }
2578 
2579  /*
2580  * otherwise, just use the type's native text representation
2581  */
2582  getTypeOutputInfo(type, &typeOut, &isvarlena);
2583  str = OidOutputFunctionCall(typeOut, value);
2584 
2585  /* ... exactly as-is for XML, and when escaping is not wanted */
2586  if (type == XMLOID || !xml_escape_strings)
2587  return str;
2588 
2589  /* otherwise, translate special characters as needed */
2590  return escape_xml(str);
2591  }
2592 }
#define DatumGetArrayTypeP(X)
Definition: array.h:254
#define ARR_ELEMTYPE(a)
Definition: array.h:285
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3578
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:313
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4231
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4116
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1830
signed short int16
Definition: c.h:482
int64 Timestamp
Definition: timestamp.h:38
int64 TimestampTz
Definition: timestamp.h:39
int32 fsec_t
Definition: timestamp.h:41
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:168
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:209
#define DATE_NOT_FINITE(j)
Definition: date.h:43
int32 DateADT
Definition: date.h:23
static DateADT DatumGetDateADT(Datum X)
Definition: date.h:54
#define PG_RE_THROW()
Definition: elog.h:411
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_CATCH(...)
Definition: elog.h:380
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1746
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define MAXDATELEN
Definition: datetime.h:200
static struct @148 value
static struct pg_tm tm
Definition: localtime.c:104
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2889
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2253
#define type_is_array_domain(typid)
Definition: lsyscache.h:209
char * pstrdup(const char *in)
Definition: mcxt.c:1644
void pfree(void *pointer)
Definition: mcxt.c:1456
#define USE_XSD_DATES
Definition: miscadmin.h:233
long date
Definition: pgtypes_date.h:9
int64 timestamp
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
uintptr_t Datum
Definition: postgres.h:64
Definition: pgtime.h:35
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_year
Definition: pgtime.h:41
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
const char * type
char * escape_xml(const char *str)
Definition: xml.c:2603
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2384
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
@ PG_XML_STRICTNESS_ALL
Definition: xml.h:44

References appendStringInfoString(), ARR_ELEMTYPE, buf, DATE_NOT_FINITE, DatumGetArrayTypeP, DatumGetBool(), DatumGetByteaPP, DatumGetDateADT(), DatumGetTimestamp(), deconstruct_array(), EncodeDateOnly(), EncodeDateTime(), ereport, errcode(), errdetail(), errmsg(), ERROR, escape_xml(), get_typlenbyvalalign(), getBaseType(), getTypeOutputInfo(), i, initStringInfo(), j2date(), MAXDATELEN, 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(), generate_unaccent_rules::str, timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, type, type_is_array_domain, USE_XSD_DATES, value, VARDATA_ANY, VARSIZE_ANY_EXHDR, xml_ereport(), xmlbinary, and XMLBINARY_BASE64.

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

◆ map_xml_name_to_sql_identifier()

char* map_xml_name_to_sql_identifier ( const char *  name)

Definition at line 2342 of file xml.c.

2343 {
2345  const char *p;
2346 
2347  initStringInfo(&buf);
2348 
2349  for (p = name; *p; p += pg_mblen(p))
2350  {
2351  if (*p == '_' && *(p + 1) == 'x'
2352  && isxdigit((unsigned char) *(p + 2))
2353  && isxdigit((unsigned char) *(p + 3))
2354  && isxdigit((unsigned char) *(p + 4))
2355  && isxdigit((unsigned char) *(p + 5))
2356  && *(p + 6) == '_')
2357  {
2358  char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
2359  unsigned int u;
2360 
2361  sscanf(p + 2, "%X", &u);
2362  pg_unicode_to_server(u, (unsigned char *) cbuf);
2363  appendStringInfoString(&buf, cbuf);
2364  p += 6;
2365  }
2366  else
2368  }
2369 
2370  return buf.data;
2371 }
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:865
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329

References appendBinaryStringInfo(), appendStringInfoString(), buf, initStringInfo(), MAX_UNICODE_EQUIVALENT_STRING, name, pg_mblen(), and pg_unicode_to_server().

Referenced by get_rule_expr().

◆ query_to_oid_list()

static List* query_to_oid_list ( const char *  query)
static

Definition at line 2692 of file xml.c.

2693 {
2694  uint64 i;
2695  List *list = NIL;
2696  int spi_result;
2697 
2698  spi_result = SPI_execute(query, true, 0);
2699  if (spi_result != SPI_OK_SELECT)
2700  elog(ERROR, "SPI_execute returned %s for %s",
2701  SPI_result_code_string(spi_result), query);
2702 
2703  for (i = 0; i < SPI_processed; i++)
2704  {
2705  Datum oid;
2706  bool isnull;
2707 
2708  oid = SPI_getbinval(SPI_tuptable->vals[i],
2710  1,
2711  &isnull);
2712  if (!isnull)
2714  }
2715 
2716  return list;
2717 }
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
SPITupleTable * SPI_tuptable
Definition: spi.c:46
const char * SPI_result_code_string(int code)
Definition: spi.c:1970
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:594
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1250
#define SPI_OK_SELECT
Definition: spi.h:86
TupleDesc tupdesc
Definition: spi.h:25
HeapTuple * vals
Definition: spi.h:26

References DatumGetObjectId(), elog(), ERROR, i, lappend_oid(), sort-test::list, NIL, SPI_execute(), SPI_getbinval(), SPI_OK_SELECT, SPI_processed, SPI_result_code_string(), 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().

◆ query_to_xml()

Datum query_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2805 of file xml.c.

2806 {
2807  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2808  bool nulls = PG_GETARG_BOOL(1);
2809  bool tableforest = PG_GETARG_BOOL(2);
2810  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2811 
2813  NULL, nulls, tableforest,
2814  targetns, true)));
2815 }
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:2907

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

◆ query_to_xml_and_xmlschema()

Datum query_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3051 of file xml.c.

3052 {
3053  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3054  bool nulls = PG_GETARG_BOOL(1);
3055  bool tableforest = PG_GETARG_BOOL(2);
3056  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3057 
3058  const char *xmlschema;
3059  SPIPlanPtr plan;
3060  Portal portal;
3061 
3062  SPI_connect();
3063 
3064  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3065  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3066 
3067  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3068  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3069 
3070  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
3071  InvalidOid, nulls, tableforest, targetns));
3072  SPI_cursor_close(portal);
3073  SPI_finish();
3074 
3076  xmlschema, nulls, tableforest,
3077  targetns, true)));
3078 }
#define plan(x)
Definition: pg_regress.c:154
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1443
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:858
void SPI_cursor_close(Portal portal)
Definition: spi.c:1860

References _SPI_strdup(), elog(), ERROR, InvalidOid, map_sql_table_to_xmlschema(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, plan, 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.

◆ query_to_xml_internal()

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

2910 {
2911  StringInfo result;
2912  char *xmltn;
2913  uint64 i;
2914 
2915  if (tablename)
2916  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2917  else
2918  xmltn = "table";
2919 
2920  result = makeStringInfo();
2921 
2922  SPI_connect();
2923  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2924  ereport(ERROR,
2925  (errcode(ERRCODE_DATA_EXCEPTION),
2926  errmsg("invalid query")));
2927 
2928  if (!tableforest)
2929  {
2930  xmldata_root_element_start(result, xmltn, xmlschema,
2931  targetns, top_level);
2932  appendStringInfoChar(result, '\n');
2933  }
2934 
2935  if (xmlschema)
2936  appendStringInfo(result, "%s\n\n", xmlschema);
2937 
2938  for (i = 0; i < SPI_processed; i++)
2939  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2940  tableforest, targetns, top_level);
2941 
2942  if (!tableforest)
2943  xmldata_root_element_end(result, xmltn);
2944 
2945  SPI_finish();
2946 
2947  return result;
2948 }

References appendStringInfo(), appendStringInfoChar(), ereport, errcode(), errmsg(), ERROR, i, makeStringInfo(), map_sql_identifier_to_xml_name(), 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().

◆ query_to_xmlschema()

Datum query_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2971 of file xml.c.

2972 {
2973  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2974  bool nulls = PG_GETARG_BOOL(1);
2975  bool tableforest = PG_GETARG_BOOL(2);
2976  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2977  const char *result;
2978  SPIPlanPtr plan;
2979  Portal portal;
2980 
2981  SPI_connect();
2982 
2983  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2984  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2985 
2986  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2987  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2988 
2990  InvalidOid, nulls,
2991  tableforest, targetns));
2992  SPI_cursor_close(portal);
2993  SPI_finish();
2994 
2996 }

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

◆ schema_get_xml_visible_tables()

static List* schema_get_xml_visible_tables ( Oid  nspid)
static

Definition at line 2721 of file xml.c.

2722 {
2723  StringInfoData query;
2724 
2725  initStringInfo(&query);
2726  appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2727  " WHERE relnamespace = %u AND relkind IN ("
2728  CppAsString2(RELKIND_RELATION) ","
2729  CppAsString2(RELKIND_MATVIEW) ","
2730  CppAsString2(RELKIND_VIEW) ")"
2731  " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2732  " ORDER BY relname;", nspid);
2733 
2734  return query_to_oid_list(query.data);
2735 }

References appendStringInfo(), CppAsString2, StringInfoData::data, initStringInfo(), nspid, and query_to_oid_list().

Referenced by schema_to_xml_internal(), and schema_to_xmlschema_internal().

◆ schema_to_xml()

Datum schema_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 3130 of file xml.c.

3131 {
3132  Name name = PG_GETARG_NAME(0);
3133  bool nulls = PG_GETARG_BOOL(1);
3134  bool tableforest = PG_GETARG_BOOL(2);
3135  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3136 
3137  char *schemaname;
3138  Oid nspid;
3139 
3140  schemaname = NameStr(*name);
3141  nspid = LookupExplicitNamespace(schemaname, false);
3142 
3144  nulls, tableforest, targetns, true)));
3145 }
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2918
Definition: c.h:730

References LookupExplicitNamespace(), name, NameStr, nspid, 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().

◆ schema_to_xml_and_xmlschema()

Datum schema_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3234 of file xml.c.

3235 {
3236  Name name = PG_GETARG_NAME(0);
3237  bool nulls = PG_GETARG_BOOL(1);
3238  bool tableforest = PG_GETARG_BOOL(2);
3239  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3240  char *schemaname;
3241  Oid nspid;
3242  StringInfo xmlschema;
3243 
3244  schemaname = NameStr(*name);
3245  nspid = LookupExplicitNamespace(schemaname, false);
3246 
3247  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3248  tableforest, targetns);
3249 
3251  xmlschema->data, nulls,
3252  tableforest, targetns, true)));
3253 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3176

References StringInfoData::data, LookupExplicitNamespace(), name, NameStr, nspid, 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().

◆ schema_to_xml_internal()

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

3089 {
3090  StringInfo result;
3091  char *xmlsn;
3092  List *relid_list;
3093  ListCell *cell;
3094 
3096  true, false);
3097  result = makeStringInfo();
3098 
3099  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
3100  appendStringInfoChar(result, '\n');
3101 
3102  if (xmlschema)
3103  appendStringInfo(result, "%s\n\n", xmlschema);
3104 
3105  SPI_connect();
3106 
3107  relid_list = schema_get_xml_visible_tables(nspid);
3108 
3109  foreach(cell, relid_list)
3110  {
3111  Oid relid = lfirst_oid(cell);
3112  StringInfo subres;
3113 
3114  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
3115  targetns, false);
3116 
3117  appendBinaryStringInfo(result, subres->data, subres->len);
3118  appendStringInfoChar(result, '\n');
3119  }
3120 
3121  SPI_finish();
3122 
3123  xmldata_root_element_end(result, xmlsn);
3124 
3125  return result;
3126 }
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2721
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2774

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), StringInfoData::data, get_namespace_name(), StringInfoData::len, lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), nspid, 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().

◆ schema_to_xmlschema()

Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3221 of file xml.c.

3222 {
3223  Name name = PG_GETARG_NAME(0);
3224  bool nulls = PG_GETARG_BOOL(1);
3225  bool tableforest = PG_GETARG_BOOL(2);
3226  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3227 
3229  nulls, tableforest, targetns)));
3230 }

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

◆ schema_to_xmlschema_internal()

static StringInfo schema_to_xmlschema_internal ( const char *  schemaname,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3176 of file xml.c.

3178 {
3179  Oid nspid;
3180  List *relid_list;
3181  List *tupdesc_list;
3182  ListCell *cell;
3183  StringInfo result;
3184 
3185  result = makeStringInfo();
3186 
3187  nspid = LookupExplicitNamespace(schemaname, false);
3188 
3189  xsd_schema_element_start(result, targetns);
3190 
3191  SPI_connect();
3192 
3193  relid_list = schema_get_xml_visible_tables(nspid);
3194 
3195  tupdesc_list = NIL;
3196  foreach(cell, relid_list)
3197  {
3198  Relation rel;
3199 
3200  rel = table_open(lfirst_oid(cell), AccessShareLock);
3201  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3202  table_close(rel, NoLock);
3203  }
3204 
3205  appendStringInfoString(result,
3206  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3207 
3208  appendStringInfoString(result,
3210  nulls, tableforest, targetns));
3211 
3212  xsd_schema_element_end(result);
3213 
3214  SPI_finish();
3215 
3216  return result;
3217 }
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3527

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

Referenced by schema_to_xml_and_xmlschema(), and schema_to_xmlschema().

◆ SPI_sql_row_to_xmlelement()

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

3995 {
3996  int i;
3997  char *xmltn;
3998 
3999  if (tablename)
4000  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
4001  else
4002  {
4003  if (tableforest)
4004  xmltn = "row";
4005  else
4006  xmltn = "table";
4007  }
4008 
4009  if (tableforest)
4010  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
4011  else
4012  appendStringInfoString(result, "<row>\n");
4013 
4014  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
4015  {
4016  char *colname;
4017  Datum colval;
4018  bool isnull;
4019 
4021  true, false);
4022  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
4024  i,
4025  &isnull);
4026  if (isnull)
4027  {
4028  if (nulls)
4029  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
4030  }
4031  else
4032  appendStringInfo(result, " <%s>%s</%s>\n",
4033  colname,
4035  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
4036  colname);
4037  }
4038 
4039  if (tableforest)
4040  {
4041  xmldata_root_element_end(result, xmltn);
4042  appendStringInfoChar(result, '\n');
4043  }
4044  else
4045  appendStringInfoString(result, "</row>\n\n");
4046 }
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1306
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1196

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), i, map_sql_identifier_to_xml_name(), map_sql_value_to_xml_value(), TupleDescData::natts, 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().

◆ stringinfo_to_xmltype()

◆ table_to_xml()

Datum table_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2791 of file xml.c.

2792 {
2793  Oid relid = PG_GETARG_OID(0);
2794  bool nulls = PG_GETARG_BOOL(1);
2795  bool tableforest = PG_GETARG_BOOL(2);
2796  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2797 
2799  nulls, tableforest,
2800  targetns, true)));
2801 }
#define PG_GETARG_OID(n)
Definition: fmgr.h:275

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

◆ table_to_xml_and_xmlschema()

Datum table_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3030 of file xml.c.

3031 {
3032  Oid relid = PG_GETARG_OID(0);
3033  bool nulls = PG_GETARG_BOOL(1);
3034  bool tableforest = PG_GETARG_BOOL(2);
3035  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3036  Relation rel;
3037  const char *xmlschema;
3038 
3039  rel = table_open(relid, AccessShareLock);
3040  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3041  tableforest, targetns);
3042  table_close(rel, NoLock);
3043 
3045  xmlschema, nulls, tableforest,
3046  targetns, true)));
3047 }

References AccessShareLock, 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_close(), table_open(), table_to_xml_internal(), and text_to_cstring().

◆ table_to_xml_internal()

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

2777 {
2778  StringInfoData query;
2779 
2780  initStringInfo(&query);
2781  appendStringInfo(&query, "SELECT * FROM %s",
2783  ObjectIdGetDatum(relid))));
2784  return query_to_xml_internal(query.data, get_rel_name(relid),
2785  xmlschema, nulls, tableforest,
2786  targetns, top_level);
2787 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:943

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().

◆ table_to_xmlschema()

Datum table_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2952 of file xml.c.

2953 {
2954  Oid relid = PG_GETARG_OID(0);
2955  bool nulls = PG_GETARG_BOOL(1);
2956  bool tableforest = PG_GETARG_BOOL(2);
2957  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2958  const char *result;
2959  Relation rel;
2960 
2961  rel = table_open(relid, AccessShareLock);
2962  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2963  tableforest, targetns);
2964  table_close(rel, NoLock);
2965 
2967 }

References AccessShareLock, cstring_to_xmltype(), map_sql_table_to_xmlschema(), NoLock, PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, RelationData::rd_att, table_close(), table_open(), and text_to_cstring().

◆ texttoxml()

Datum texttoxml ( PG_FUNCTION_ARGS  )

Definition at line 606 of file xml.c.

607 {
609 
611 }
const void * data
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:929
int xmloption
Definition: xml.c:100

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

◆ xml_in()

Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 263 of file xml.c.

264 {
265 #ifdef USE_LIBXML
266  char *s = PG_GETARG_CSTRING(0);
267  xmltype *vardata;
268  xmlDocPtr doc;
269 
270  /* Build the result object. */
271  vardata = (xmltype *) cstring_to_text(s);
272 
273  /*
274  * Parse the data to check if it is well-formed XML data.
275  *
276  * Note: we don't need to worry about whether a soft error is detected.
277  */
278  doc = xml_parse(vardata, xmloption, true, GetDatabaseEncoding(),
279  NULL, NULL, fcinfo->context);
280  if (doc != NULL)
281  xmlFreeDoc(doc);
282 
283  PG_RETURN_XML_P(vardata);
284 #else
285  NO_XML_SUPPORT();
286  return 0;
287 #endif
288 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268

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

◆ xml_is_document()

bool xml_is_document ( xmltype arg)

Definition at line 1065 of file xml.c.

1066 {
1067 #ifdef USE_LIBXML
1068  xmlDocPtr doc;
1069  ErrorSaveContext escontext = {T_ErrorSaveContext};
1070 
1071  /*
1072  * We'll report "true" if no soft error is reported by xml_parse().
1073  */
1074  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
1075  GetDatabaseEncoding(), NULL, NULL, (Node *) &escontext);
1076  if (doc)
1077  xmlFreeDoc(doc);
1078 
1079  return !escontext.error_occurred;
1080 #else /* not USE_LIBXML */
1081  NO_XML_SUPPORT();
1082  return false;
1083 #endif /* not USE_LIBXML */
1084 }
void * arg
@ XMLOPTION_DOCUMENT
Definition: primnodes.h:1519
bool error_occurred
Definition: miscnodes.h:46
Definition: nodes.h:129

References arg, ErrorSaveContext::error_occurred, GetDatabaseEncoding(), NO_XML_SUPPORT, and XMLOPTION_DOCUMENT.

Referenced by ExecEvalXmlExpr().

◆ xml_is_well_formed()

Datum xml_is_well_formed ( PG_FUNCTION_ARGS  )

Definition at line 4509 of file xml.c.

4510 {
4511 #ifdef USE_LIBXML
4512  text *data = PG_GETARG_TEXT_PP(0);
4513 
4514  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4515 #else
4516  NO_XML_SUPPORT();
4517  return 0;
4518 #endif /* not USE_LIBXML */
4519 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

References data, NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and xmloption.

◆ xml_is_well_formed_content()

Datum xml_is_well_formed_content ( PG_FUNCTION_ARGS  )

Definition at line 4535 of file xml.c.

4536 {
4537 #ifdef USE_LIBXML
4538  text *data = PG_GETARG_TEXT_PP(0);
4539 
4540  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4541 #else
4542  NO_XML_SUPPORT();
4543  return 0;
4544 #endif /* not USE_LIBXML */
4545 }
@ XMLOPTION_CONTENT
Definition: primnodes.h:1520

References data, NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_CONTENT.

◆ xml_is_well_formed_document()

Datum xml_is_well_formed_document ( PG_FUNCTION_ARGS  )

Definition at line 4522 of file xml.c.

4523 {
4524 #ifdef USE_LIBXML
4525  text *data = PG_GETARG_TEXT_PP(0);
4526 
4527  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4528 #else
4529  NO_XML_SUPPORT();
4530  return 0;
4531 #endif /* not USE_LIBXML */
4532 }

References data, NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.

◆ xml_out()

Datum xml_out ( PG_FUNCTION_ARGS  )

Definition at line 346 of file xml.c.

347 {
348  xmltype *x = PG_GETARG_XML_P(0);
349 
350  /*
351  * xml_out removes the encoding property in all cases. This is because we
352  * cannot control from here whether the datum will be converted to a
353  * different client encoding, so we'd do more harm than good by including
354  * it.
355  */
357 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int x
Definition: isn.c:71
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:302
#define PG_GETARG_XML_P(n)
Definition: xml.h:62

References PG_GETARG_XML_P, PG_RETURN_CSTRING, x, and xml_out_internal().

◆ xml_out_internal()

static char* xml_out_internal ( xmltype x,
pg_enc  target_encoding 
)
static

Definition at line 302 of file xml.c.

303 {
304  char *str = text_to_cstring((text *) x);
305 
306 #ifdef USE_LIBXML
307  size_t len = strlen(str);
308  xmlChar *version;
309  int standalone;
310  int res_code;
311 
312  if ((res_code = parse_xml_decl((xmlChar *) str,
313  &len, &version, NULL, &standalone)) == 0)
314  {
316 
318 
319  if (!print_xml_decl(&buf, version, target_encoding, standalone))
320  {
321  /*
322  * If we are not going to produce an XML declaration, eat a single
323  * newline in the original string to prevent empty first lines in
324  * the output.
325  */
326  if (*(str + len) == '\n')
327  len += 1;
328  }
330 
331  pfree(str);
332 
333  return buf.data;
334  }
335 
337  errcode(ERRCODE_INTERNAL_ERROR),
338  errmsg_internal("could not parse XML declaration in stored value"),
339  errdetail_for_xml_code(res_code));
340 #endif
341  return str;
342 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
#define WARNING
Definition: elog.h:36

References appendStringInfoString(), buf, ereport, errcode(), errmsg_internal(), initStringInfo(), len, pfree(), generate_unaccent_rules::str, text_to_cstring(), WARNING, and x.

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

◆ xml_recv()

Datum xml_recv ( PG_FUNCTION_ARGS  )

Definition at line 361 of file xml.c.

362 {
363 #ifdef USE_LIBXML
365  xmltype *result;
366  char *str;
367  char *newstr;
368  int nbytes;
369  xmlDocPtr doc;
370  xmlChar *encodingStr = NULL;
371  int encoding;
372 
373  /*
374  * Read the data in raw format. We don't know yet what the encoding is, as
375  * that information is embedded in the xml declaration; so we have to
376  * parse that before converting to server encoding.
377  */
378  nbytes = buf->len - buf->cursor;
379  str = (char *) pq_getmsgbytes(buf, nbytes);
380 
381  /*
382  * We need a null-terminated string to pass to parse_xml_decl(). Rather
383  * than make a separate copy, make the temporary result one byte bigger
384  * than it needs to be.
385  */
386  result = palloc(nbytes + 1 + VARHDRSZ);
387  SET_VARSIZE(result, nbytes + VARHDRSZ);
388  memcpy(VARDATA(result), str, nbytes);
389  str = VARDATA(result);
390  str[nbytes] = '\0';
391 
392  parse_xml_decl((const xmlChar *) str, NULL, NULL, &encodingStr, NULL);
393 
394  /*
395  * If encoding wasn't explicitly specified in the XML header, treat it as
396  * UTF-8, as that's the default in XML. This is different from xml_in(),
397  * where the input has to go through the normal client to server encoding
398  * conversion.
399  */
400  encoding = encodingStr ? xmlChar_to_encoding(encodingStr) : PG_UTF8;
401 
402  /*
403  * Parse the data to check if it is well-formed XML data. Assume that
404  * xml_parse will throw ERROR if not.
405  */
406  doc = xml_parse(result, xmloption, true, encoding, NULL, NULL, NULL);
407  xmlFreeDoc(doc);
408 
409  /* Now that we know what we're dealing with, convert to server encoding */
410  newstr = pg_any_to_server(str, nbytes, encoding);
411 
412  if (newstr != str)
413  {
414  pfree(result);
415  result = (xmltype *) cstring_to_text(newstr);
416  pfree(newstr);
417  }
418 
419  PG_RETURN_XML_P(result);
420 #else
421  NO_XML_SUPPORT();
422  return 0;
423 #endif
424 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:677
void * palloc(Size size)
Definition: mcxt.c:1226
int32 encoding
Definition: pg_database.h:41
@ PG_UTF8
Definition: pg_wchar.h:232
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:511
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define VARDATA(PTR)
Definition: varatt.h:278
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References buf, cstring_to_text(), encoding, NO_XML_SUPPORT, palloc(), pfree(), pg_any_to_server(), PG_GETARG_POINTER, PG_RETURN_XML_P, PG_UTF8, pq_getmsgbytes(), SET_VARSIZE, generate_unaccent_rules::str, VARDATA, VARHDRSZ, and xmloption.

◆ xml_send()

Datum xml_send ( PG_FUNCTION_ARGS  )

Definition at line 428 of file xml.c.

429 {
430  xmltype *x = PG_GETARG_XML_P(0);
431  char *outval;
433 
434  /*
435  * xml_out_internal doesn't convert the encoding, it just prints the right
436  * declaration. pq_sendtext will do the conversion.
437  */
439 
441  pq_sendtext(&buf, outval, strlen(outval));
442  pfree(outval);
444 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
int pg_get_client_encoding(void)
Definition: mbutils.c:337
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:175
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349

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

◆ xmlcomment()

Datum xmlcomment ( PG_FUNCTION_ARGS  )

Definition at line 481 of file xml.c.

482 {
483 #ifdef USE_LIBXML
484  text *arg = PG_GETARG_TEXT_PP(0);
485  char *argdata = VARDATA_ANY(arg);
486  int len = VARSIZE_ANY_EXHDR(arg);
488  int i;
489 
490  /* check for "--" in string or "-" at the end */
491  for (i = 1; i < len; i++)
492  {
493  if (argdata[i] == '-' && argdata[i - 1] == '-')
494  ereport(ERROR,
495  (errcode(ERRCODE_INVALID_XML_COMMENT),
496  errmsg("invalid XML comment")));
497  }
498  if (len > 0 && argdata[len - 1] == '-')
499  ereport(ERROR,
500  (errcode(ERRCODE_INVALID_XML_COMMENT),
501  errmsg("invalid XML comment")));
502 
504  appendStringInfoString(&buf, "<!--");
506  appendStringInfoString(&buf, "-->");
507 
509 #else
510  NO_XML_SUPPORT();
511  return 0;
512 #endif
513 }
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3979

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

◆ xmlconcat()

xmltype* xmlconcat ( List args)

Definition at line 522 of file xml.c.

523 {
524 #ifdef USE_LIBXML
525  int global_standalone = 1;
526  xmlChar *global_version = NULL;
527  bool global_version_no_value = false;
529  ListCell *v;
530 
532  foreach(v, args)
533  {
535  size_t len;
536  xmlChar *version;
537  int standalone;
538  char *str;
539 
540  len = VARSIZE(x) - VARHDRSZ;
541  str = text_to_cstring((text *) x);
542 
543  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
544 
545  if (standalone == 0 && global_standalone == 1)
546  global_standalone = 0;
547  if (standalone < 0)
548  global_standalone = -1;
549 
550  if (!version)
551  global_version_no_value = true;
552  else if (!global_version)
553  global_version = version;
554  else if (xmlStrcmp(version, global_version) != 0)
555  global_version_no_value = true;
556 
558  pfree(str);
559  }
560 
561  if (!global_version_no_value || global_standalone >= 0)
562  {
563  StringInfoData buf2;
564 
565  initStringInfo(&buf2);
566 
567  print_xml_decl(&buf2,
568  (!global_version_no_value) ? global_version : NULL,
569  0,
570  global_standalone);
571 
572  appendBinaryStringInfo(&buf2, buf.data, buf.len);
573  buf = buf2;
574  }
575 
576  return stringinfo_to_xmltype(&buf);
577 #else
578  NO_XML_SUPPORT();
579  return NULL;
580 #endif
581 }
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
#define VARSIZE(PTR)
Definition: varatt.h:279
static xmltype * DatumGetXmlP(Datum X)
Definition: xml.h:51

References appendBinaryStringInfo(), appendStringInfoString(), generate_unaccent_rules::args, buf, DatumGetXmlP(), initStringInfo(), len, lfirst, NO_XML_SUPPORT, pfree(), PointerGetDatum(), generate_unaccent_rules::str, stringinfo_to_xmltype(), text_to_cstring(), VARHDRSZ, VARSIZE, and x.

Referenced by ExecEvalXmlExpr(), and xmlconcat2().

◆ xmlconcat2()

Datum xmlconcat2 ( PG_FUNCTION_ARGS  )

Definition at line 588 of file xml.c.

589 {
590  if (PG_ARGISNULL(0))
591  {
592  if (PG_ARGISNULL(1))
593  PG_RETURN_NULL();
594  else
596  }
597  else if (PG_ARGISNULL(1))
599  else
601  PG_GETARG_XML_P(1))));
602 }
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define list_make2(x1, x2)
Definition: pg_list.h:214
xmltype * xmlconcat(List *args)
Definition: xml.c:522

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

◆ xmldata_root_element_end()

static void xmldata_root_element_end ( StringInfo  result,
const char *  eltname 
)
static

Definition at line 2900 of file xml.c.

2901 {
2902  appendStringInfo(result, "</%s>\n", eltname);
2903 }

References appendStringInfo().

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

◆ xmldata_root_element_start()

static void xmldata_root_element_start ( StringInfo  result,
const char *  eltname,
const char *  xmlschema,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2873 of file xml.c.

2876 {
2877  /* This isn't really wrong but currently makes no sense. */
2878  Assert(top_level || !xmlschema);
2879 
2880  appendStringInfo(result, "<%s", eltname);
2881  if (top_level)
2882  {
2883  appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2884  if (strlen(targetns) > 0)
2885  appendStringInfo(result, " xmlns=\"%s\"", targetns);
2886  }
2887  if (xmlschema)
2888  {
2889  /* FIXME: better targets */
2890  if (strlen(targetns) > 0)
2891  appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2892  else
2893  appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2894  }
2895  appendStringInfoString(result, ">\n");
2896 }
#define NAMESPACE_XSI
Definition: xml.c:234

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

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

◆ xmlelement()

xmltype* xmlelement ( XmlExpr xexpr,
Datum named_argvalue,
bool named_argnull,
Datum argvalue,
bool argnull 
)

Definition at line 805 of file xml.c.

808 {
809 #ifdef USE_LIBXML
810  xmltype *result;
811  List *named_arg_strings;
812  List *arg_strings;
813  int i;
814  ListCell *arg;
815  ListCell *narg;
816  PgXmlErrorContext *xmlerrcxt;
817  volatile xmlBufferPtr buf = NULL;
818  volatile xmlTextWriterPtr writer = NULL;
819 
820  /*
821  * All arguments are already evaluated, and their values are passed in the
822  * named_argvalue/named_argnull or argvalue/argnull arrays. This avoids
823  * issues if one of the arguments involves a call to some other function
824  * or subsystem that wants to use libxml on its own terms. We examine the
825  * original XmlExpr to identify the numbers and types of the arguments.
826  */
827  named_arg_strings = NIL;
828  i = 0;
829  foreach(arg, xexpr->named_args)
830  {
831  Expr *e = (Expr *) lfirst(arg);
832  char *str;
833 
834  if (named_argnull[i])
835  str = NULL;
836  else
837  str = map_sql_value_to_xml_value(named_argvalue[i],
838  exprType((Node *) e),
839  false);
840  named_arg_strings = lappend(named_arg_strings, str);
841  i++;
842  }
843 
844  arg_strings = NIL;
845  i = 0;
846  foreach(arg, xexpr->args)
847  {
848  Expr *e = (Expr *) lfirst(arg);
849  char *str;
850 
851  /* here we can just forget NULL elements immediately */
852  if (!argnull[i])
853  {
854  str = map_sql_value_to_xml_value(argvalue[i],
855  exprType((Node *) e),
856  true);
857  arg_strings = lappend(arg_strings, str);
858  }
859  i++;
860  }
861 
862  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
863 
864  PG_TRY();
865  {
866  buf = xmlBufferCreate();
867  if (buf == NULL || xmlerrcxt->err_occurred)
868  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
869  "could not allocate xmlBuffer");
870  writer = xmlNewTextWriterMemory(buf, 0);
871  if (writer == NULL || xmlerrcxt->err_occurred)
872  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
873  "could not allocate xmlTextWriter");
874 
875  xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
876 
877  forboth(arg, named_arg_strings, narg, xexpr->arg_names)
878  {
879  char *str = (char *) lfirst(arg);
880  char *argname = strVal(lfirst(narg));
881 
882  if (str)
883  xmlTextWriterWriteAttribute(writer,
884  (xmlChar *) argname,
885  (xmlChar *) str);
886  }
887 
888  foreach(arg, arg_strings)
889  {
890  char *str = (char *) lfirst(arg);
891 
892  xmlTextWriterWriteRaw(writer, (xmlChar *) str);
893  }
894 
895  xmlTextWriterEndElement(writer);
896 
897  /* we MUST do this now to flush data out to the buffer ... */
898  xmlFreeTextWriter(writer);
899  writer = NULL;
900 
901  result = xmlBuffer_to_xmltype(buf);
902  }
903  PG_CATCH();
904  {
905  if (writer)
906  xmlFreeTextWriter(writer);
907  if (buf)
908  xmlBufferFree(buf);
909 
910  pg_xml_done(xmlerrcxt, true);
911 
912  PG_RE_THROW();
913  }
914  PG_END_TRY();
915 
916  xmlBufferFree(buf);
917 
918  pg_xml_done(xmlerrcxt, false);
919 
920  return result;
921 #else
922  NO_XML_SUPPORT();
923  return NULL;
924 #endif
925 }
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:43
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:467
e
Definition: preproc-init.c:82
List * args
Definition: primnodes.h:1535
List * named_args
Definition: primnodes.h:1531
#define strVal(v)
Definition: value.h:82

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

Referenced by ExecEvalXmlExpr().

◆ xmlexists()

Datum xmlexists ( PG_FUNCTION_ARGS  )

Definition at line 4444 of file xml.c.

4445 {
4446 #ifdef USE_LIBXML
4447  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4449  int res_nitems;
4450 
4451  xpath_internal(xpath_expr_text, data, NULL,
4452  &res_nitems, NULL);
4453 
4454  PG_RETURN_BOOL(res_nitems > 0);
4455 #else
4456  NO_XML_SUPPORT();
4457  return 0;
4458 #endif
4459 }

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

◆ xmlparse()

xmltype* xmlparse ( text data,
XmlOptionType  xmloption_arg,
bool  preserve_whitespace 
)

Definition at line 929 of file xml.c.

930 {
931 #ifdef USE_LIBXML
932  xmlDocPtr doc;
933 
934  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
935  GetDatabaseEncoding(), NULL, NULL, NULL);
936  xmlFreeDoc(doc);
937 
938  return (xmltype *) data;
939 #else
940  NO_XML_SUPPORT();
941  return NULL;
942 #endif
943 }

References data, GetDatabaseEncoding(), and NO_XML_SUPPORT.

Referenced by ExecEvalXmlExpr(), and texttoxml().

◆ xmlpi()

xmltype* xmlpi ( const char *  target,
text arg,
bool  arg_is_null,
bool result_is_null 
)

Definition at line 947 of file xml.c.

948 {
949 #ifdef USE_LIBXML
950  xmltype *result;
952 
953  if (pg_strcasecmp(target, "xml") == 0)
954  ereport(ERROR,
955  (errcode(ERRCODE_SYNTAX_ERROR), /* really */
956  errmsg("invalid XML processing instruction"),
957  errdetail("XML processing instruction target name cannot be \"%s\".", target)));
958 
959  /*
960  * Following the SQL standard, the null check comes after the syntax check
961  * above.
962  */
963  *result_is_null = arg_is_null;
964  if (*result_is_null)
965  return NULL;
966 
968 
969  appendStringInfo(&buf, "<?%s", target);
970 
971  if (arg != NULL)
972  {
973  char *string;
974 
975  string = text_to_cstring(arg);
976  if (strstr(string, "?>") != NULL)
977  ereport(ERROR,
978  (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
979  errmsg("invalid XML processing instruction"),
980  errdetail("XML processing instruction cannot contain \"?>\".")));
981 
982  appendStringInfoChar(&buf, ' ');
983  appendStringInfoString(&buf, string + strspn(string, " "));
984  pfree(string);
985  }
986  appendStringInfoString(&buf, "?>");
987 
988  result = stringinfo_to_xmltype(&buf);
989  pfree(buf.data);
990  return result;
991 #else
992  NO_XML_SUPPORT();
993  return NULL;
994 #endif
995 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char string[11]
Definition: preproc-type.c:52

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

Referenced by ExecEvalXmlExpr().

◆ xmlroot()

xmltype* xmlroot ( xmltype data,
text version,
int  standalone 
)

Definition at line 999 of file xml.c.

1000 {
1001 #ifdef USE_LIBXML
1002  char *str;
1003  size_t len;
1004  xmlChar *orig_version;
1005  int orig_standalone;
1007 
1008  len = VARSIZE(data) - VARHDRSZ;
1009  str = text_to_cstring((text *) data);
1010 
1011  parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
1012 
1013  if (version)
1014  orig_version = xml_text2xmlChar(version);
1015  else
1016  orig_version = NULL;
1017 
1018  switch (standalone)
1019  {
1020  case XML_STANDALONE_YES:
1021  orig_standalone = 1;
1022  break;
1023  case XML_STANDALONE_NO:
1024  orig_standalone = 0;
1025  break;
1027  orig_standalone = -1;
1028  break;
1030  /* leave original value */
1031  break;
1032  }
1033 
1034  initStringInfo(&buf);
1035  print_xml_decl(&buf, orig_version, 0, orig_standalone);
1037 
1038  return stringinfo_to_xmltype(&buf);
1039 #else
1040  NO_XML_SUPPORT();
1041  return NULL;
1042 #endif
1043 }
@ XML_STANDALONE_OMITTED
Definition: xml.h:30
@ XML_STANDALONE_NO_VALUE
Definition: xml.h:29
@ XML_STANDALONE_YES
Definition: xml.h:27
@ XML_STANDALONE_NO
Definition: xml.h:28

References appendStringInfoString(), buf, data, initStringInfo(), len, NO_XML_SUPPORT, generate_unaccent_rules::str, 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().

◆ XmlTableDestroyOpaque()

static void XmlTableDestroyOpaque ( struct TableFuncScanState state)
static

Definition at line 4973 of file xml.c.

4974 {
4975 #ifdef USE_LIBXML
4976  XmlTableBuilderData *xtCxt;
4977 
4978  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
4979 
4980  /* Propagate our own error context to libxml2 */
4981  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4982 
4983  if (xtCxt->xpathscomp != NULL)
4984  {
4985  int i;
4986 
4987  for (i = 0; i < xtCxt->natts; i++)
4988  if (xtCxt->xpathscomp[i] != NULL)
4989  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
4990  }
4991 
4992  if (xtCxt->xpathobj != NULL)
4993  xmlXPathFreeObject(xtCxt->xpathobj);
4994  if (xtCxt->xpathcomp != NULL)
4995  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
4996  if (xtCxt->xpathcxt != NULL)
4997  xmlXPathFreeContext(xtCxt->xpathcxt);
4998  if (xtCxt->doc != NULL)
4999  xmlFreeDoc(xtCxt->doc);
5000  if (xtCxt->ctxt != NULL)
5001  xmlFreeParserCtxt(xtCxt->ctxt);
5002 
5003  pg_xml_done(xtCxt->xmlerrcxt, true);
5004 
5005  /* not valid anymore */
5006  xtCxt->magic = 0;
5007  state->opaque = NULL;
5008 
5009 #else
5010  NO_XML_SUPPORT();
5011 #endif /* not USE_LIBXML */
5012 }
Definition: regguts.h:323

References i, NO_XML_SUPPORT, and pg_xml_done().

◆ XmlTableFetchRow()

static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4776 of file xml.c.

4777 {
4778 #ifdef USE_LIBXML
4779  XmlTableBuilderData *xtCxt;
4780 
4781  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4782 
4783  /* Propagate our own error context to libxml2 */
4784  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4785 
4786  if (xtCxt->xpathobj == NULL)
4787  {
4788  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4789  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4790  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4791  "could not create XPath object");
4792 
4793  xtCxt->row_count = 0;
4794  }
4795 
4796  if (xtCxt->xpathobj->type == XPATH_NODESET)
4797  {
4798  if (xtCxt->xpathobj->nodesetval != NULL)
4799  {
4800  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4801  return true;
4802  }
4803  }
4804 
4805  return false;
4806 #else
4807  NO_XML_SUPPORT();
4808  return false;
4809 #endif /* not USE_LIBXML */
4810 }

References ERROR, NO_XML_SUPPORT, and xml_ereport().

◆ XmlTableGetValue()

static Datum XmlTableGetValue ( struct TableFuncScanState state,
int  colnum,
Oid  typid,
int32  typmod,
bool isnull 
)
static

Definition at line 4821 of file xml.c.

4823 {
4824 #ifdef USE_LIBXML
4825  XmlTableBuilderData *xtCxt;
4826  Datum result = (Datum) 0;
4827  xmlNodePtr cur;
4828  char *cstr = NULL;
4829  volatile xmlXPathObjectPtr xpathobj = NULL;
4830 
4831  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4832 
4833  Assert(xtCxt->xpathobj &&
4834  xtCxt->xpathobj->type == XPATH_NODESET &&
4835  xtCxt->xpathobj->nodesetval != NULL);
4836 
4837  /* Propagate our own error context to libxml2 */
4838  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4839 
4840  *isnull = false;
4841 
4842  cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
4843 
4844  Assert(xtCxt->xpathscomp[colnum] != NULL);
4845 
4846  PG_TRY();
4847  {
4848  /* Set current node as entry point for XPath evaluation */
4849  xtCxt->xpathcxt->node = cur;
4850 
4851  /* Evaluate column path */
4852  xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
4853  if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4854  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4855  "could not create XPath object");
4856 
4857  /*
4858  * There are four possible cases, depending on the number of nodes
4859  * returned by the XPath expression and the type of the target column:
4860  * a) XPath returns no nodes. b) The target type is XML (return all
4861  * as XML). For non-XML return types: c) One node (return content).
4862  * d) Multiple nodes (error).
4863  */
4864  if (xpathobj->type == XPATH_NODESET)
4865  {
4866  int count = 0;
4867 
4868  if (xpathobj->nodesetval != NULL)
4869  count = xpathobj->nodesetval->nodeNr;
4870 
4871  if (xpathobj->nodesetval == NULL || count == 0)
4872  {
4873  *isnull = true;
4874  }
4875  else
4876  {
4877  if (typid == XMLOID)
4878  {
4879  text *textstr;
4881 
4882  /* Concatenate serialized values */
4883  initStringInfo(&str);
4884  for (int i = 0; i < count; i++)
4885  {
4886  textstr =
4887  xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
4888  xtCxt->xmlerrcxt);
4889 
4890  appendStringInfoText(&str, textstr);
4891  }
4892  cstr = str.data;
4893  }
4894  else
4895  {
4896  xmlChar *str;
4897 
4898  if (count > 1)
4899  ereport(ERROR,
4900  (errcode(ERRCODE_CARDINALITY_VIOLATION),
4901  errmsg("more than one value returned by column XPath expression")));
4902 
4903  str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);
4904  cstr = str ? xml_pstrdup_and_free(str) : "";
4905  }
4906  }
4907  }
4908  else if (xpathobj->type == XPATH_STRING)
4909  {
4910  /* Content should be escaped when target will be XML */
4911  if (typid == XMLOID)
4912  cstr = escape_xml((char *) xpathobj->stringval);
4913  else
4914  cstr = (char *) xpathobj->stringval;
4915  }
4916  else if (xpathobj->type == XPATH_BOOLEAN)
4917  {
4918  char typcategory;
4919  bool typispreferred;
4920  xmlChar *str;
4921 
4922  /* Allow implicit casting from boolean to numbers */
4923  get_type_category_preferred(typid, &typcategory, &typispreferred);
4924 
4925  if (typcategory != TYPCATEGORY_NUMERIC)
4926  str = xmlXPathCastBooleanToString(xpathobj->boolval);
4927  else
4928  str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval));
4929 
4930  cstr = xml_pstrdup_and_free(str);
4931  }
4932  else if (xpathobj->type == XPATH_NUMBER)
4933  {
4934  xmlChar *str;
4935 
4936  str = xmlXPathCastNumberToString(xpathobj->floatval);
4937  cstr = xml_pstrdup_and_free(str);
4938  }
4939  else
4940  elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
4941 
4942  /*
4943  * By here, either cstr contains the result value, or the isnull flag
4944  * has been set.
4945  */
4946  Assert(cstr || *isnull);
4947 
4948  if (!*isnull)
4949  result = InputFunctionCall(&state->in_functions[colnum],
4950  cstr,
4951  state->typioparams[colnum],
4952  typmod);
4953  }
4954  PG_FINALLY();
4955  {
4956  if (xpathobj != NULL)
4957  xmlXPathFreeObject(xpathobj);
4958  }
4959  PG_END_TRY();
4960 
4961  return result;
4962 #else
4963  NO_XML_SUPPORT();
4964  return 0;
4965 #endif /* not USE_LIBXML */
4966 }
struct cursor * cur
Definition: ecpg.c:28
#define PG_FINALLY(...)
Definition: elog.h:387
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1513
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2692

References appendStringInfoText(), Assert(), cur, elog(), ereport, errcode(), errmsg(), ERROR, escape_xml(), get_type_category_preferred(), i, initStringInfo(), InputFunctionCall(), NO_XML_SUPPORT, PG_END_TRY, PG_FINALLY, PG_TRY, generate_unaccent_rules::str, and xml_ereport().

◆ XmlTableInitOpaque()

static void XmlTableInitOpaque ( struct TableFuncScanState state,
int  natts 
)
static

Definition at line 4584 of file xml.c.

4585 {
4586 #ifdef USE_LIBXML
4587  volatile xmlParserCtxtPtr ctxt = NULL;
4588  XmlTableBuilderData *xtCxt;
4589  PgXmlErrorContext *xmlerrcxt;
4590 
4591  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4592  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4593  xtCxt->natts = natts;
4594  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4595 
4596  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4597 
4598  PG_TRY();
4599  {
4600  xmlInitParser();
4601 
4602  ctxt = xmlNewParserCtxt();
4603  if (ctxt == NULL || xmlerrcxt->err_occurred)
4604  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4605  "could not allocate parser context");
4606  }
4607  PG_CATCH();
4608  {
4609  if (ctxt != NULL)
4610  xmlFreeParserCtxt(ctxt);
4611 
4612  pg_xml_done(xmlerrcxt, true);
4613 
4614  PG_RE_THROW();
4615  }
4616  PG_END_TRY();
4617 
4618  xtCxt->xmlerrcxt = xmlerrcxt;
4619  xtCxt->ctxt = ctxt;
4620 
4621  state->opaque = xtCxt;
4622 #else
4623  NO_XML_SUPPORT();
4624 #endif /* not USE_LIBXML */
4625 }
void * palloc0(Size size)
Definition: mcxt.c:1257

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

◆ XmlTableSetColumnFilter()

static void XmlTableSetColumnFilter ( struct TableFuncScanState state,
const char *  path,
int  colnum 
)
static

Definition at line 4744 of file xml.c.

4745 {
4746 #ifdef USE_LIBXML
4747  XmlTableBuilderData *xtCxt;
4748  xmlChar *xstr;
4749 
4750  Assert(PointerIsValid(path));
4751 
4752  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4753 
4754  if (*path == '\0')
4755  ereport(ERROR,
4756  (errcode(ERRCODE_DATA_EXCEPTION),
4757  errmsg("column path filter must not be empty string")));
4758 
4759  xstr = pg_xmlCharStrndup(path, strlen(path));
4760 
4761  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4762  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4763  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4764  "invalid XPath expression");
4765 #else
4766  NO_XML_SUPPORT();
4767 #endif /* not USE_LIBXML */
4768 }
#define PointerIsValid(pointer)
Definition: c.h:752

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

◆ XmlTableSetDocument()

static void XmlTableSetDocument ( struct TableFuncScanState state,
Datum  value 
)
static

Definition at line 4632 of file xml.c.

4633 {
4634 #ifdef USE_LIBXML
4635  XmlTableBuilderData *xtCxt;
4636  xmltype *xmlval = DatumGetXmlP(value);
4637  char *str;
4638  xmlChar *xstr;
4639  int length;
4640  volatile xmlDocPtr doc = NULL;
4641  volatile xmlXPathContextPtr xpathcxt = NULL;
4642 
4643  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4644 
4645  /*
4646  * Use out function for casting to string (remove encoding property). See
4647  * comment in xml_out.
4648  */
4649  str = xml_out_internal(xmlval, 0);
4650 
4651  length = strlen(str);
4652  xstr = pg_xmlCharStrndup(str, length);
4653 
4654  PG_TRY();
4655  {
4656  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4657  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4658  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4659  "could not parse XML document");
4660  xpathcxt = xmlXPathNewContext(doc);
4661  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4662  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4663  "could not allocate XPath context");
4664  xpathcxt->node = (xmlNodePtr) doc;
4665  }
4666  PG_CATCH();
4667  {
4668  if (xpathcxt != NULL)
4669  xmlXPathFreeContext(xpathcxt);
4670  if (doc != NULL)
4671  xmlFreeDoc(doc);
4672 
4673  PG_RE_THROW();
4674  }
4675  PG_END_TRY();
4676 
4677  xtCxt->doc = doc;
4678  xtCxt->xpathcxt = xpathcxt;
4679 #else
4680  NO_XML_SUPPORT();
4681 #endif /* not USE_LIBXML */
4682 }

References DatumGetXmlP(), ERROR, NO_XML_SUPPORT, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, generate_unaccent_rules::str, value, xml_ereport(), and xml_out_internal().

◆ XmlTableSetNamespace()

static void XmlTableSetNamespace ( struct TableFuncScanState state,
const char *  name,
const char *  uri 
)
static

Definition at line 4689 of file xml.c.

4690 {
4691 #ifdef USE_LIBXML
4692  XmlTableBuilderData *xtCxt;
4693 
4694  if (name == NULL)
4695  ereport(ERROR,
4696  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4697  errmsg("DEFAULT namespace is not supported")));
4698  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4699 
4700  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4701  pg_xmlCharStrndup(name, strlen(name)),
4702  pg_xmlCharStrndup(uri, strlen(uri))))
4703  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4704  "could not set XML namespace");
4705 #else
4706  NO_XML_SUPPORT();
4707 #endif /* not USE_LIBXML */
4708 }

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

◆ XmlTableSetRowFilter()

static void XmlTableSetRowFilter ( struct TableFuncScanState state,
const char *  path 
)
static

Definition at line 4715 of file xml.c.

4716 {
4717 #ifdef USE_LIBXML
4718  XmlTableBuilderData *xtCxt;
4719  xmlChar *xstr;
4720 
4721  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4722 
4723  if (*path == '\0')
4724  ereport(ERROR,
4725  (errcode(ERRCODE_DATA_EXCEPTION),
4726  errmsg("row path filter must not be empty string")));
4727 
4728  xstr = pg_xmlCharStrndup(path, strlen(path));
4729 
4730  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4731  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4732  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4733  "invalid XPath expression");
4734 #else
4735  NO_XML_SUPPORT();
4736 #endif /* not USE_LIBXML */
4737 }

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

◆ xmltotext()

Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 615 of file xml.c.

616 {
618 
619  /* It's actually binary compatible. */
621 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372

References data, PG_GETARG_XML_P, and PG_RETURN_TEXT_P.

◆ xmltotext_with_options()

text* xmltotext_with_options ( xmltype data,
XmlOptionType  xmloption_arg,
bool  indent 
)

Definition at line 625 of file xml.c.

626 {
627 #ifdef USE_LIBXML
628  text *volatile result;
629  xmlDocPtr doc;
630  XmlOptionType parsed_xmloptiontype;
631  xmlNodePtr content_nodes;
632  volatile xmlBufferPtr buf = NULL;
633  volatile xmlSaveCtxtPtr ctxt = NULL;
634  ErrorSaveContext escontext = {T_ErrorSaveContext};
635  PgXmlErrorContext *xmlerrcxt;
636 #endif
637 
638  if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
639  {
640  /*
641  * We don't actually need to do anything, so just return the
642  * binary-compatible input. For backwards-compatibility reasons,
643  * allow such cases to succeed even without USE_LIBXML.
644  */
645  return (text *) data;
646  }
647 
648 #ifdef USE_LIBXML
649  /* Parse the input according to the xmloption */
650  doc = xml_parse(data, xmloption_arg, true, GetDatabaseEncoding(),
651  &parsed_xmloptiontype, &content_nodes,
652  (Node *) &escontext);
653  if (doc == NULL || escontext.error_occurred)
654  {
655  if (doc)
656  xmlFreeDoc(doc);
657  /* A soft error must be failure to conform to XMLOPTION_DOCUMENT */
658  ereport(ERROR,
659  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
660  errmsg("not an XML document")));
661  }
662 
663  /* If we weren't asked to indent, we're done. */
664  if (!indent)
665  {
666  xmlFreeDoc(doc);
667  return (text *) data;
668  }
669 
670  /* Otherwise, we gotta spin up some error handling. */
671  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
672 
673  PG_TRY();
674  {
675  size_t decl_len = 0;
676 
677  /* The serialized data will go into this buffer. */
678  buf = xmlBufferCreate();
679 
680  if (buf == NULL || xmlerrcxt->err_occurred)
681  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
682  "could not allocate xmlBuffer");
683 
684  /* Detect whether there's an XML declaration */
685  parse_xml_decl(xml_text2xmlChar(data), &decl_len, NULL, NULL, NULL);
686 
687  /*
688  * Emit declaration only if the input had one. Note: some versions of
689  * xmlSaveToBuffer leak memory if a non-null encoding argument is
690  * passed, so don't do that. We don't want any encoding conversion
691  * anyway.
692  */
693  if (decl_len == 0)
694  ctxt = xmlSaveToBuffer(buf, NULL,
695  XML_SAVE_NO_DECL | XML_SAVE_FORMAT);
696  else
697  ctxt = xmlSaveToBuffer(buf, NULL,
698  XML_SAVE_FORMAT);
699 
700  if (ctxt == NULL || xmlerrcxt->err_occurred)
701  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
702  "could not allocate xmlSaveCtxt");
703 
704  if (parsed_xmloptiontype == XMLOPTION_DOCUMENT)
705  {
706  /* If it's a document, saving is easy. */
707  if (xmlSaveDoc(ctxt, doc) == -1 || xmlerrcxt->err_occurred)
708  xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
709  "could not save document to xmlBuffer");
710  }
711  else if (content_nodes != NULL)
712  {
713  /*
714  * Deal with the case where we have non-singly-rooted XML.
715  * libxml's dump functions don't work well for that without help.
716  * We build a fake root node that serves as a container for the
717  * content nodes, and then iterate over the nodes.
718  */
719  xmlNodePtr root;
720  xmlNodePtr newline;
721 
722  root = xmlNewNode(NULL, (const xmlChar *) "content-root");
723  if (root == NULL || xmlerrcxt->err_occurred)
724  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
725  "could not allocate xml node");
726 
727  /* This attaches root to doc, so we need not free it separately. */
728  xmlDocSetRootElement(doc, root);
729  xmlAddChild(root, content_nodes);
730 
731  /*
732  * We use this node to insert newlines in the dump. Note: in at
733  * least some libxml versions, xmlNewDocText would not attach the
734  * node to the document even if we passed it. Therefore, manage
735  * freeing of this node manually, and pass NULL here to make sure
736  * there's not a dangling link.
737  */
738  newline = xmlNewDocText(NULL, (const xmlChar *) "\n");
739  if (newline == NULL || xmlerrcxt->err_occurred)
740  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
741  "could not allocate xml node");
742 
743  for (xmlNodePtr node = root->children; node; node = node->next)
744  {
745  /* insert newlines between nodes */
746  if (node->type != XML_TEXT_NODE && node->prev != NULL)
747  {
748  if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
749  {
750  xmlFreeNode(newline);
751  xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
752  "could not save newline to xmlBuffer");
753  }
754  }
755 
756  if (xmlSaveTree(ctxt, node) == -1 || xmlerrcxt->err_occurred)
757  {
758  xmlFreeNode(newline);
759  xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
760  "could not save content to xmlBuffer");
761  }
762  }
763 
764  xmlFreeNode(newline);
765  }
766 
767  if (xmlSaveClose(ctxt) == -1 || xmlerrcxt->err_occurred)
768  {
769  ctxt = NULL; /* don't try to close it again */
770  xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
771  "could not close xmlSaveCtxtPtr");
772  }
773 
774  result = (text *) xmlBuffer_to_xmltype(buf);
775  }
776  PG_CATCH();
777  {
778  if (ctxt)
779  xmlSaveClose(ctxt);
780  if (buf)
781  xmlBufferFree(buf);
782  if (doc)
783  xmlFreeDoc(doc);
784 
785  pg_xml_done(xmlerrcxt, true);
786 
787  PG_RE_THROW();
788  }
789  PG_END_TRY();
790 
791  xmlBufferFree(buf);
792  xmlFreeDoc(doc);
793 
794  pg_xml_done(xmlerrcxt, false);
795 
796  return result;
797 #else
798  NO_XML_SUPPORT();
799  return NULL;
800 #endif
801 }
#define newline
Definition: indent_codes.h:35
XmlOptionType
Definition: primnodes.h:1518

References buf, data, ereport, errcode(), errmsg(), ERROR, ErrorSaveContext::error_occurred, GetDatabaseEncoding(), newline, NO_XML_SUPPORT, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, xml_ereport(), and XMLOPTION_DOCUMENT.

Referenced by ExecEvalXmlExpr().

◆ xmlvalidate()

Datum xmlvalidate ( PG_FUNCTION_ARGS  )

Definition at line 1055 of file xml.c.

1056 {
1057  ereport(ERROR,
1058  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1059  errmsg("xmlvalidate is not implemented")));
1060  return 0;
1061 }

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

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4421 of file xml.c.

4422 {
4423 #ifdef USE_LIBXML
4424  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4426  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4427  ArrayBuildState *astate;
4428 
4429  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4430  xpath_internal(xpath_expr_text, data, namespaces,
4431  NULL, astate);
4433 #else
4434  NO_XML_SUPPORT();
4435  return 0;
4436 #endif
4437 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5240
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135

References CurrentMemoryContext, data, initArrayResult(), makeArrayResult(), NO_XML_SUPPORT, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, and PG_RETURN_DATUM.

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

◆ xpath_exists()

Datum xpath_exists ( PG_FUNCTION_ARGS  )

Definition at line 4467 of file xml.c.

4468 {
4469 #ifdef USE_LIBXML
4470  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4472  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4473  int res_nitems;
4474 
4475  xpath_internal(xpath_expr_text, data, namespaces,
4476  &res_nitems, NULL);
4477 
4478  PG_RETURN_BOOL(res_nitems > 0);
4479 #else
4480  NO_XML_SUPPORT();
4481  return 0;
4482 #endif
4483 }

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

◆ xsd_schema_element_end()

static void xsd_schema_element_end ( StringInfo  result)
static

Definition at line 3169 of file xml.c.

3170 {
3171  appendStringInfoString(result, "</xsd:schema>");
3172 }

References appendStringInfoString().

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

◆ xsd_schema_element_start()

static void xsd_schema_element_start ( StringInfo  result,
const char *  targetns 
)
static

Definition at line 3152 of file xml.c.

3153 {
3154  appendStringInfoString(result,
3155  "<xsd:schema\n"
3156  " xmlns:xsd=\"" NAMESPACE_XSD "\"");
3157  if (strlen(targetns) > 0)
3158  appendStringInfo(result,
3159  "\n"
3160  " targetNamespace=\"%s\"\n"
3161  " elementFormDefault=\"qualified\"",
3162  targetns);
3163  appendStringInfoString(result,
3164  ">\n\n");
3165 }
#define NAMESPACE_XSD
Definition: xml.c:233

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

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

Variable Documentation

◆ xmlbinary

int xmlbinary = XMLBINARY_BASE64

Definition at line 99 of file xml.c.

Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().

◆ xmloption

int xmloption = XMLOPTION_CONTENT

Definition at line 100 of file xml.c.

Referenced by texttoxml(), xml_in(), xml_is_well_formed(), and xml_recv().

◆ XmlTableRoutine

const TableFuncRoutine XmlTableRoutine
Initial value:
=
{
}
static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts)
Definition: xml.c:4584
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4689
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4715
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4821
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4632
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:4973
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4776
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4744

Definition at line 213 of file xml.c.

Referenced by ExecInitTableFuncScan().