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/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)
 
Datum xmltext (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 245 of file xml.c.

◆ NAMESPACE_XSD

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

Definition at line 243 of file xml.c.

◆ NAMESPACE_XSI

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

Definition at line 244 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:1205
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

Definition at line 235 of file xml.c.

◆ PG_XML_DEFAULT_VERSION

#define PG_XML_DEFAULT_VERSION   "1.0"

Definition at line 301 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 2773 of file xml.c.

◆ XML_VISIBLE_SCHEMAS_EXCLUDE

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

Definition at line 2771 of file xml.c.

Function Documentation

◆ _SPI_strdup()

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2664 of file xml.c.

2665 {
2666  size_t len = strlen(s) + 1;
2667  char *ret = SPI_palloc(len);
2668 
2669  memcpy(ret, s, len);
2670  return ret;
2671 }
const void size_t len
void * SPI_palloc(Size size)
Definition: spi.c:1335

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

475 {
476  return (xmltype *) cstring_to_text(string);
477 }
Definition: c.h:674
text * cstring_to_text(const char *s)
Definition: varlena.c:184

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

2849 {
2851  int32 count = PG_GETARG_INT32(1);
2852  bool nulls = PG_GETARG_BOOL(2);
2853  bool tableforest = PG_GETARG_BOOL(3);
2854  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2855 
2856  StringInfoData result;
2857  Portal portal;
2858  uint64 i;
2859 
2860  initStringInfo(&result);
2861 
2862  if (!tableforest)
2863  {
2864  xmldata_root_element_start(&result, "table", NULL, targetns, true);
2865  appendStringInfoChar(&result, '\n');
2866  }
2867 
2868  SPI_connect();
2869  portal = SPI_cursor_find(name);
2870  if (portal == NULL)
2871  ereport(ERROR,
2872  (errcode(ERRCODE_UNDEFINED_CURSOR),
2873  errmsg("cursor \"%s\" does not exist", name)));
2874 
2875  SPI_cursor_fetch(portal, true, count);
2876  for (i = 0; i < SPI_processed; i++)
2877  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2878  tableforest, targetns, true);
2879 
2880  SPI_finish();
2881 
2882  if (!tableforest)
2883  xmldata_root_element_end(&result, "table");
2884 
2886 }
signed int int32
Definition: c.h:481
#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:44
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1791
int SPI_connect(void)
Definition: spi.c:94
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1803
int SPI_finish(void)
Definition: spi.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * text_to_cstring(const text *t)
Definition: varlena.c:217
const char * name
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:467
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2902
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2929
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:4021
#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 3029 of file xml.c.

3030 {
3032  bool nulls = PG_GETARG_BOOL(1);
3033  bool tableforest = PG_GETARG_BOOL(2);
3034  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3035  const char *xmlschema;
3036  Portal portal;
3037 
3038  SPI_connect();
3039  portal = SPI_cursor_find(name);
3040  if (portal == NULL)
3041  ereport(ERROR,
3042  (errcode(ERRCODE_UNDEFINED_CURSOR),
3043  errmsg("cursor \"%s\" does not exist", name)));
3044  if (portal->tupDesc == NULL)
3045  ereport(ERROR,
3046  (errcode(ERRCODE_INVALID_CURSOR_STATE),
3047  errmsg("portal \"%s\" does not return tuples", name)));
3048 
3049  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
3050  InvalidOid, nulls,
3051  tableforest, targetns));
3052  SPI_finish();
3053 
3054  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
3055 }
#define InvalidOid
Definition: postgres_ext.h:36
TupleDesc tupDesc
Definition: portal.h:160
static char * _SPI_strdup(const char *s)
Definition: xml.c:2664
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:474
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3451

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

2778 {
2779  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2780 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2721
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2773

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

2785 {
2786  /* At the moment there is no order required here. */
2787  return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2788  " WHERE relkind IN ("
2789  CppAsString2(RELKIND_RELATION) ","
2790  CppAsString2(RELKIND_MATVIEW) ","
2791  CppAsString2(RELKIND_VIEW) ")"
2792  " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2793  " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2794 }
#define CppAsString2(x)
Definition: c.h:314

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

3335 {
3336  bool nulls = PG_GETARG_BOOL(0);
3337  bool tableforest = PG_GETARG_BOOL(1);
3338  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3339 
3341  tableforest, targetns)));
3342 }
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3291

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

3402 {
3403  bool nulls = PG_GETARG_BOOL(0);
3404  bool tableforest = PG_GETARG_BOOL(1);
3405  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3406  StringInfo xmlschema;
3407 
3408  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3409 
3411  nulls, tableforest, targetns)));
3412 }
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3346

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

3293 {
3294  StringInfo result;
3295  List *nspid_list;
3296  ListCell *cell;
3297  char *xmlcn;
3298 
3300  true, false);
3301  result = makeStringInfo();
3302 
3303  xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
3304  appendStringInfoChar(result, '\n');
3305 
3306  if (xmlschema)
3307  appendStringInfo(result, "%s\n\n", xmlschema);
3308 
3309  SPI_connect();
3310 
3311  nspid_list = database_get_xml_visible_schemas();
3312 
3313  foreach(cell, nspid_list)
3314  {
3315  Oid nspid = lfirst_oid(cell);
3316  StringInfo subres;
3317 
3318  subres = schema_to_xml_internal(nspid, NULL, nulls,
3319  tableforest, targetns, false);
3320 
3321  appendBinaryStringInfo(result, subres->data, subres->len);
3322  appendStringInfoChar(result, '\n');
3323  }
3324 
3325  SPI_finish();
3326 
3327  xmldata_root_element_end(result, xmlcn);
3328 
3329  return result;
3330 }
int nspid
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3153
Oid MyDatabaseId
Definition: globals.c:91
#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:97
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
Definition: pg_list.h:54
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2315
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3116
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2777

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

3390 {
3391  bool nulls = PG_GETARG_BOOL(0);
3392  bool tableforest = PG_GETARG_BOOL(1);
3393  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3394 
3396  tableforest, targetns)));
3397 }

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

3348 {
3349  List *relid_list;
3350  List *nspid_list;
3351  List *tupdesc_list;
3352  ListCell *cell;
3353  StringInfo result;
3354 
3355  result = makeStringInfo();
3356 
3357  xsd_schema_element_start(result, targetns);
3358 
3359  SPI_connect();
3360 
3361  relid_list = database_get_xml_visible_tables();
3362  nspid_list = database_get_xml_visible_schemas();
3363 
3364  tupdesc_list = NIL;
3365  foreach(cell, relid_list)
3366  {
3367  Relation rel;
3368 
3369  rel = table_open(lfirst_oid(cell), AccessShareLock);
3370  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3371  table_close(rel, NoLock);
3372  }
3373 
3374  appendStringInfoString(result,
3375  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3376 
3377  appendStringInfoString(result,
3378  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3379 
3380  xsd_schema_element_end(result);
3381 
3382  SPI_finish();
3383 
3384  return result;
3385 }
List * lappend(List *list, void *datum)
Definition: list.c:339
#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:182
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:133
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2784
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3629
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:3181
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3791
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:3198

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

2633 {
2635  const char *p;
2636 
2637  initStringInfo(&buf);
2638  for (p = str; *p; p++)
2639  {
2640  switch (*p)
2641  {
2642  case '&':
2643  appendStringInfoString(&buf, "&amp;");
2644  break;
2645  case '<':
2646  appendStringInfoString(&buf, "&lt;");
2647  break;
2648  case '>':
2649  appendStringInfoString(&buf, "&gt;");
2650  break;
2651  case '\r':
2652  appendStringInfoString(&buf, "&#x0d;");
2653  break;
2654  default:
2656  break;
2657  }
2658  }
2659  return buf.data;
2660 }
static char * buf
Definition: pg_test_fsync.c:73
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:204

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

3421 {
3422  StringInfoData result;
3423 
3424  initStringInfo(&result);
3425 
3426  if (a)
3427  appendStringInfoString(&result,
3428  map_sql_identifier_to_xml_name(a, true, true));
3429  if (b)
3430  appendStringInfo(&result, ".%s",
3431  map_sql_identifier_to_xml_name(b, true, true));
3432  if (c)
3433  appendStringInfo(&result, ".%s",
3434  map_sql_identifier_to_xml_name(c, true, true));
3435  if (d)
3436  appendStringInfo(&result, ".%s",
3437  map_sql_identifier_to_xml_name(d, true, true));
3438 
3439  return result.data;
3440 }
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 3629 of file xml.c.

3631 {
3632  char *dbname;
3633  char *xmlcn;
3634  char *catalogtypename;
3635  StringInfoData result;
3636  ListCell *cell;
3637 
3639 
3640  initStringInfo(&result);
3641 
3642  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3643 
3644  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3645  dbname,
3646  NULL,
3647  NULL);
3648 
3649  appendStringInfo(&result,
3650  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3651  appendStringInfoString(&result,
3652  " <xsd:all>\n");
3653 
3654  foreach(cell, nspid_list)
3655  {
3656  Oid nspid = lfirst_oid(cell);
3657  char *nspname = get_namespace_name(nspid);
3658  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3659  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3660  dbname,
3661  nspname,
3662  NULL);
3663 
3664  appendStringInfo(&result,
3665  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3666  xmlsn, schematypename);
3667  }
3668 
3669  appendStringInfoString(&result,
3670  " </xsd:all>\n");
3671  appendStringInfoString(&result,
3672  "</xsd:complexType>\n\n");
3673 
3674  appendStringInfo(&result,
3675  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3676  xmlcn, catalogtypename);
3677 
3678  return result.data;
3679 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3322
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:3420

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

2317 {
2318 #ifdef USE_LIBXML
2320  const char *p;
2321 
2322  /*
2323  * SQL/XML doesn't make use of this case anywhere, so it's probably a
2324  * mistake.
2325  */
2326  Assert(fully_escaped || !escape_period);
2327 
2328  initStringInfo(&buf);
2329 
2330  for (p = ident; *p; p += pg_mblen(p))
2331  {
2332  if (*p == ':' && (p == ident || fully_escaped))
2333  appendStringInfoString(&buf, "_x003A_");
2334  else if (*p == '_' && *(p + 1) == 'x')
2335  appendStringInfoString(&buf, "_x005F_");
2336  else if (fully_escaped && p == ident &&
2337  pg_strncasecmp(p, "xml", 3) == 0)
2338  {
2339  if (*p == 'x')
2340  appendStringInfoString(&buf, "_x0078_");
2341  else
2342  appendStringInfoString(&buf, "_x0058_");
2343  }
2344  else if (escape_period && *p == '.')
2345  appendStringInfoString(&buf, "_x002E_");
2346  else
2347  {
2348  pg_wchar u = sqlchar_to_unicode(p);
2349 
2350  if ((p == ident)
2351  ? !is_valid_xml_namefirst(u)
2352  : !is_valid_xml_namechar(u))
2353  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
2354  else
2356  }
2357  }
2358 
2359  return buf.data;
2360 #else /* not USE_LIBXML */
2361  NO_XML_SUPPORT();
2362  return NULL;
2363 #endif /* not USE_LIBXML */
2364 }
#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:1023
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define NO_XML_SUPPORT()
Definition: xml.c:235

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

3558 {
3559  char *dbname;
3560  char *nspname;
3561  char *xmlsn;
3562  char *schematypename;
3563  StringInfoData result;
3564  ListCell *cell;
3565 
3567  nspname = get_namespace_name(nspid);
3568 
3569  initStringInfo(&result);
3570 
3571  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3572 
3573  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3574  dbname,
3575  nspname,
3576  NULL);
3577 
3578  appendStringInfo(&result,
3579  "<xsd:complexType name=\"%s\">\n", schematypename);
3580  if (!tableforest)
3581  appendStringInfoString(&result,
3582  " <xsd:all>\n");
3583  else
3584  appendStringInfoString(&result,
3585  " <xsd:sequence>\n");
3586 
3587  foreach(cell, relid_list)
3588  {
3589  Oid relid = lfirst_oid(cell);
3590  char *relname = get_rel_name(relid);
3591  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3592  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3593  dbname,
3594  nspname,
3595  relname);
3596 
3597  if (!tableforest)
3598  appendStringInfo(&result,
3599  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3600  xmltn, tabletypename);
3601  else
3602  appendStringInfo(&result,
3603  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3604  xmltn, tabletypename);
3605  }
3606 
3607  if (!tableforest)
3608  appendStringInfoString(&result,
3609  " </xsd:all>\n");
3610  else
3611  appendStringInfoString(&result,
3612  " </xsd:sequence>\n");
3613  appendStringInfoString(&result,
3614  "</xsd:complexType>\n\n");
3615 
3616  appendStringInfo(&result,
3617  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3618  xmlsn, schematypename);
3619 
3620  return result.data;
3621 }
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1906
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 3451 of file xml.c.

3453 {
3454  int i;
3455  char *xmltn;
3456  char *tabletypename;
3457  char *rowtypename;
3458  StringInfoData result;
3459 
3460  initStringInfo(&result);
3461 
3462  if (OidIsValid(relid))
3463  {
3464  HeapTuple tuple;
3465  Form_pg_class reltuple;
3466 
3467  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3468  if (!HeapTupleIsValid(tuple))
3469  elog(ERROR, "cache lookup failed for relation %u", relid);
3470  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3471 
3472  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3473  true, false);
3474 
3475  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3477  get_namespace_name(reltuple->relnamespace),
3478  NameStr(reltuple->relname));
3479 
3480  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3482  get_namespace_name(reltuple->relnamespace),
3483  NameStr(reltuple->relname));
3484 
3485  ReleaseSysCache(tuple);
3486  }
3487  else
3488  {
3489  if (tableforest)
3490  xmltn = "row";
3491  else
3492  xmltn = "table";
3493 
3494  tabletypename = "TableType";
3495  rowtypename = "RowType";
3496  }
3497 
3498  xsd_schema_element_start(&result, targetns);
3499 
3500  appendStringInfoString(&result,
3502 
3503  appendStringInfo(&result,
3504  "<xsd:complexType name=\"%s\">\n"
3505  " <xsd:sequence>\n",
3506  rowtypename);
3507 
3508  for (i = 0; i < tupdesc->natts; i++)
3509  {
3510  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3511 
3512  if (att->attisdropped)
3513  continue;
3514  appendStringInfo(&result,
3515  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3517  true, false),
3518  map_sql_type_to_xml_name(att->atttypid, -1),
3519  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3520  }
3521 
3522  appendStringInfoString(&result,
3523  " </xsd:sequence>\n"
3524  "</xsd:complexType>\n\n");
3525 
3526  if (!tableforest)
3527  {
3528  appendStringInfo(&result,
3529  "<xsd:complexType name=\"%s\">\n"
3530  " <xsd:sequence>\n"
3531  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3532  " </xsd:sequence>\n"
3533  "</xsd:complexType>\n\n",
3534  tabletypename, rowtypename);
3535 
3536  appendStringInfo(&result,
3537  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3538  xmltn, tabletypename);
3539  }
3540  else
3541  appendStringInfo(&result,
3542  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3543  xmltn, rowtypename);
3544 
3545  xsd_schema_element_end(&result);
3546 
3547  return result.data;
3548 }
#define NameStr(name)
Definition: c.h:733
#define OidIsValid(objectId)
Definition: c.h:762
#define elog(elevel,...)
Definition: elog.h:224
#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:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3686

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(), 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 3686 of file xml.c.

3687 {
3688  StringInfoData result;
3689 
3690  initStringInfo(&result);
3691 
3692  switch (typeoid)
3693  {
3694  case BPCHAROID:
3695  if (typmod == -1)
3696  appendStringInfoString(&result, "CHAR");
3697  else
3698  appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3699  break;
3700  case VARCHAROID:
3701  if (typmod == -1)
3702  appendStringInfoString(&result, "VARCHAR");
3703  else
3704  appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3705  break;
3706  case NUMERICOID:
3707  if (typmod == -1)
3708  appendStringInfoString(&result, "NUMERIC");
3709  else
3710  appendStringInfo(&result, "NUMERIC_%d_%d",
3711  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3712  (typmod - VARHDRSZ) & 0xffff);
3713  break;
3714  case INT4OID:
3715  appendStringInfoString(&result, "INTEGER");
3716  break;
3717  case INT2OID:
3718  appendStringInfoString(&result, "SMALLINT");
3719  break;
3720  case INT8OID:
3721  appendStringInfoString(&result, "BIGINT");
3722  break;
3723  case FLOAT4OID:
3724  appendStringInfoString(&result, "REAL");
3725  break;
3726  case FLOAT8OID:
3727  appendStringInfoString(&result, "DOUBLE");
3728  break;
3729  case BOOLOID:
3730  appendStringInfoString(&result, "BOOLEAN");
3731  break;
3732  case TIMEOID:
3733  if (typmod == -1)
3734  appendStringInfoString(&result, "TIME");
3735  else
3736  appendStringInfo(&result, "TIME_%d", typmod);
3737  break;
3738  case TIMETZOID:
3739  if (typmod == -1)
3740  appendStringInfoString(&result, "TIME_WTZ");
3741  else
3742  appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3743  break;
3744  case TIMESTAMPOID:
3745  if (typmod == -1)
3746  appendStringInfoString(&result, "TIMESTAMP");
3747  else
3748  appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3749  break;
3750  case TIMESTAMPTZOID:
3751  if (typmod == -1)
3752  appendStringInfoString(&result, "TIMESTAMP_WTZ");
3753  else
3754  appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3755  break;
3756  case DATEOID:
3757  appendStringInfoString(&result, "DATE");
3758  break;
3759  case XMLOID:
3760  appendStringInfoString(&result, "XML");
3761  break;
3762  default:
3763  {
3764  HeapTuple tuple;
3765  Form_pg_type typtuple;
3766 
3767  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3768  if (!HeapTupleIsValid(tuple))
3769  elog(ERROR, "cache lookup failed for type %u", typeoid);
3770  typtuple = (Form_pg_type) GETSTRUCT(tuple);
3771 
3772  appendStringInfoString(&result,
3773  map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3775  get_namespace_name(typtuple->typnamespace),
3776  NameStr(typtuple->typname)));
3777 
3778  ReleaseSysCache(tuple);
3779  }
3780  }
3781 
3782  return result.data;
3783 }
#define VARHDRSZ
Definition: c.h:679
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261

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(), 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 3846 of file xml.c.

3847 {
3848  StringInfoData result;
3849  const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3850 
3851  initStringInfo(&result);
3852 
3853  if (typeoid == XMLOID)
3854  {
3855  appendStringInfoString(&result,
3856  "<xsd:complexType mixed=\"true\">\n"
3857  " <xsd:sequence>\n"
3858  " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3859  " </xsd:sequence>\n"
3860  "</xsd:complexType>\n");
3861  }
3862  else
3863  {
3864  appendStringInfo(&result,
3865  "<xsd:simpleType name=\"%s\">\n", typename);
3866 
3867  switch (typeoid)
3868  {
3869  case BPCHAROID:
3870  case VARCHAROID:
3871  case TEXTOID:
3872  appendStringInfoString(&result,
3873  " <xsd:restriction base=\"xsd:string\">\n");
3874  if (typmod != -1)
3875  appendStringInfo(&result,
3876  " <xsd:maxLength value=\"%d\"/>\n",
3877  typmod - VARHDRSZ);
3878  appendStringInfoString(&result, " </xsd:restriction>\n");
3879  break;
3880 
3881  case BYTEAOID:
3882  appendStringInfo(&result,
3883  " <xsd:restriction base=\"xsd:%s\">\n"
3884  " </xsd:restriction>\n",
3885  xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3886  break;
3887 
3888  case NUMERICOID:
3889  if (typmod != -1)
3890  appendStringInfo(&result,
3891  " <xsd:restriction base=\"xsd:decimal\">\n"
3892  " <xsd:totalDigits value=\"%d\"/>\n"
3893  " <xsd:fractionDigits value=\"%d\"/>\n"
3894  " </xsd:restriction>\n",
3895  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3896  (typmod - VARHDRSZ) & 0xffff);
3897  break;
3898 
3899  case INT2OID:
3900  appendStringInfo(&result,
3901  " <xsd:restriction base=\"xsd:short\">\n"
3902  " <xsd:maxInclusive value=\"%d\"/>\n"
3903  " <xsd:minInclusive value=\"%d\"/>\n"
3904  " </xsd:restriction>\n",
3905  SHRT_MAX, SHRT_MIN);
3906  break;
3907 
3908  case INT4OID:
3909  appendStringInfo(&result,
3910  " <xsd:restriction base=\"xsd:int\">\n"
3911  " <xsd:maxInclusive value=\"%d\"/>\n"
3912  " <xsd:minInclusive value=\"%d\"/>\n"
3913  " </xsd:restriction>\n",
3914  INT_MAX, INT_MIN);
3915  break;
3916 
3917  case INT8OID:
3918  appendStringInfo(&result,
3919  " <xsd:restriction base=\"xsd:long\">\n"
3920  " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3921  " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3922  " </xsd:restriction>\n",
3923  PG_INT64_MAX,
3924  PG_INT64_MIN);
3925  break;
3926 
3927  case FLOAT4OID:
3928  appendStringInfoString(&result,
3929  " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3930  break;
3931 
3932  case FLOAT8OID:
3933  appendStringInfoString(&result,
3934  " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3935  break;
3936 
3937  case BOOLOID:
3938  appendStringInfoString(&result,
3939  " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
3940  break;
3941 
3942  case TIMEOID:
3943  case TIMETZOID:
3944  {
3945  const char *tz = (typeoid == TIMETZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3946 
3947  if (typmod == -1)
3948  appendStringInfo(&result,
3949  " <xsd:restriction base=\"xsd:time\">\n"
3950  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3951  " </xsd:restriction>\n", tz);
3952  else if (typmod == 0)
3953  appendStringInfo(&result,
3954  " <xsd:restriction base=\"xsd:time\">\n"
3955  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3956  " </xsd:restriction>\n", tz);
3957  else
3958  appendStringInfo(&result,
3959  " <xsd:restriction base=\"xsd:time\">\n"
3960  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3961  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3962  break;
3963  }
3964 
3965  case TIMESTAMPOID:
3966  case TIMESTAMPTZOID:
3967  {
3968  const char *tz = (typeoid == TIMESTAMPTZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3969 
3970  if (typmod == -1)
3971  appendStringInfo(&result,
3972  " <xsd:restriction base=\"xsd:dateTime\">\n"
3973  " <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"
3974  " </xsd:restriction>\n", tz);
3975  else if (typmod == 0)
3976  appendStringInfo(&result,
3977  " <xsd:restriction base=\"xsd:dateTime\">\n"
3978  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3979  " </xsd:restriction>\n", tz);
3980  else
3981  appendStringInfo(&result,
3982  " <xsd:restriction base=\"xsd:dateTime\">\n"
3983  " <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"
3984  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3985  break;
3986  }
3987 
3988  case DATEOID:
3989  appendStringInfoString(&result,
3990  " <xsd:restriction base=\"xsd:date\">\n"
3991  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
3992  " </xsd:restriction>\n");
3993  break;
3994 
3995  default:
3996  if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
3997  {
3998  Oid base_typeoid;
3999  int32 base_typmod = -1;
4000 
4001  base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
4002 
4003  appendStringInfo(&result,
4004  " <xsd:restriction base=\"%s\"/>\n",
4005  map_sql_type_to_xml_name(base_typeoid, base_typmod));
4006  }
4007  break;
4008  }
4009  appendStringInfoString(&result, "</xsd:simpleType>\n");
4010  }
4011 
4012  return result.data;
4013 }
#define INT64_FORMAT
Definition: c.h:535
#define PG_INT64_MAX
Definition: c.h:579
#define PG_INT64_MIN
Definition: c.h:578
char get_typtype(Oid typid)
Definition: lsyscache.c:2585
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2494
int xmlbinary
Definition: xml.c:109
@ 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 3791 of file xml.c.

3792 {
3793  List *uniquetypes = NIL;
3794  int i;
3795  StringInfoData result;
3796  ListCell *cell0;
3797 
3798  /* extract all column types used in the set of TupleDescs */
3799  foreach(cell0, tupdesc_list)
3800  {
3801  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3802 
3803  for (i = 0; i < tupdesc->natts; i++)
3804  {
3805  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3806 
3807  if (att->attisdropped)
3808  continue;
3809  uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3810  }
3811  }
3812 
3813  /* add base types of domains */
3814  foreach(cell0, uniquetypes)
3815  {
3816  Oid typid = lfirst_oid(cell0);
3817  Oid basetypid = getBaseType(typid);
3818 
3819  if (basetypid != typid)
3820  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3821  }
3822 
3823  /* Convert to textual form */
3824  initStringInfo(&result);
3825 
3826  foreach(cell0, uniquetypes)
3827  {
3828  appendStringInfo(&result, "%s\n",
3830  -1));
3831  }
3832 
3833  return result.data;
3834 }
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1380
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2477
#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:3846

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

2414 {
2416  {
2417  ArrayType *array;
2418  Oid elmtype;
2419  int16 elmlen;
2420  bool elmbyval;
2421  char elmalign;
2422  int num_elems;
2423  Datum *elem_values;
2424  bool *elem_nulls;
2426  int i;
2427 
2428  array = DatumGetArrayTypeP(value);
2429  elmtype = ARR_ELEMTYPE(array);
2430  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2431 
2432  deconstruct_array(array, elmtype,
2433  elmlen, elmbyval, elmalign,
2434  &elem_values, &elem_nulls,
2435  &num_elems);
2436 
2437  initStringInfo(&buf);
2438 
2439  for (i = 0; i < num_elems; i++)
2440  {
2441  if (elem_nulls[i])
2442  continue;
2443  appendStringInfoString(&buf, "<element>");
2445  map_sql_value_to_xml_value(elem_values[i],
2446  elmtype, true));
2447  appendStringInfoString(&buf, "</element>");
2448  }
2449 
2450  pfree(elem_values);
2451  pfree(elem_nulls);
2452 
2453  return buf.data;
2454  }
2455  else
2456  {
2457  Oid typeOut;
2458  bool isvarlena;
2459  char *str;
2460 
2461  /*
2462  * Flatten domains; the special-case treatments below should apply to,
2463  * eg, domains over boolean not just boolean.
2464  */
2465  type = getBaseType(type);
2466 
2467  /*
2468  * Special XSD formatting for some data types
2469  */
2470  switch (type)
2471  {
2472  case BOOLOID:
2473  if (DatumGetBool(value))
2474  return "true";
2475  else
2476  return "false";
2477 
2478  case DATEOID:
2479  {
2480  DateADT date;
2481  struct pg_tm tm;
2482  char buf[MAXDATELEN + 1];
2483 
2485  /* XSD doesn't support infinite values */
2486  if (DATE_NOT_FINITE(date))
2487  ereport(ERROR,
2488  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2489  errmsg("date out of range"),
2490  errdetail("XML does not support infinite date values.")));
2492  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2494 
2495  return pstrdup(buf);
2496  }
2497 
2498  case TIMESTAMPOID:
2499  {
2501  struct pg_tm tm;
2502  fsec_t fsec;
2503  char buf[MAXDATELEN + 1];
2504 
2506 
2507  /* XSD doesn't support infinite values */
2509  ereport(ERROR,
2510  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2511  errmsg("timestamp out of range"),
2512  errdetail("XML does not support infinite timestamp values.")));
2513  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2514  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2515  else
2516  ereport(ERROR,
2517  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2518  errmsg("timestamp out of range")));
2519 
2520  return pstrdup(buf);
2521  }
2522 
2523  case TIMESTAMPTZOID:
2524  {
2526  struct pg_tm tm;
2527  int tz;
2528  fsec_t fsec;
2529  const char *tzn = NULL;
2530  char buf[MAXDATELEN + 1];
2531 
2533 
2534  /* XSD doesn't support infinite values */
2536  ereport(ERROR,
2537  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2538  errmsg("timestamp out of range"),
2539  errdetail("XML does not support infinite timestamp values.")));
2540  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2541  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2542  else
2543  ereport(ERROR,
2544  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2545  errmsg("timestamp out of range")));
2546 
2547  return pstrdup(buf);
2548  }
2549 
2550 #ifdef USE_LIBXML
2551  case BYTEAOID:
2552  {
2553  bytea *bstr = DatumGetByteaPP(value);
2554  PgXmlErrorContext *xmlerrcxt;
2555  volatile xmlBufferPtr buf = NULL;
2556  volatile xmlTextWriterPtr writer = NULL;
2557  char *result;
2558 
2559  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2560 
2561  PG_TRY();
2562  {
2563  buf = xmlBufferCreate();
2564  if (buf == NULL || xmlerrcxt->err_occurred)
2565  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2566  "could not allocate xmlBuffer");
2567  writer = xmlNewTextWriterMemory(buf, 0);
2568  if (writer == NULL || xmlerrcxt->err_occurred)
2569  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2570  "could not allocate xmlTextWriter");
2571 
2572  if (xmlbinary == XMLBINARY_BASE64)
2573  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2574  0, VARSIZE_ANY_EXHDR(bstr));
2575  else
2576  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2577  0, VARSIZE_ANY_EXHDR(bstr));
2578 
2579  /* we MUST do this now to flush data out to the buffer */
2580  xmlFreeTextWriter(writer);
2581  writer = NULL;
2582 
2583  result = pstrdup((const char *) xmlBufferContent(buf));
2584  }
2585  PG_CATCH();
2586  {
2587  if (writer)
2588  xmlFreeTextWriter(writer);
2589  if (buf)
2590  xmlBufferFree(buf);
2591 
2592  pg_xml_done(xmlerrcxt, true);
2593 
2594  PG_RE_THROW();
2595  }
2596  PG_END_TRY();
2597 
2598  xmlBufferFree(buf);
2599 
2600  pg_xml_done(xmlerrcxt, false);
2601 
2602  return result;
2603  }
2604 #endif /* USE_LIBXML */
2605 
2606  }
2607 
2608  /*
2609  * otherwise, just use the type's native text representation
2610  */
2611  getTypeOutputInfo(type, &typeOut, &isvarlena);
2612  str = OidOutputFunctionCall(typeOut, value);
2613 
2614  /* ... exactly as-is for XML, and when escaping is not wanted */
2615  if (type == XMLOID || !xml_escape_strings)
2616  return str;
2617 
2618  /* otherwise, translate special characters as needed */
2619  return escape_xml(str);
2620  }
2621 }
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3612
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:311
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4331
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4216
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1901
signed short int16
Definition: c.h:480
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:169
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
#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:1763
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define MAXDATELEN
Definition: datetime.h:200
static struct @150 value
static struct pg_tm tm
Definition: localtime.c:104
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2863
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2227
#define type_is_array_domain(typid)
Definition: lsyscache.h:208
char * pstrdup(const char *in)
Definition: mcxt.c:1683
void pfree(void *pointer)
Definition: mcxt.c:1508
#define USE_XSD_DATES
Definition: miscadmin.h:238
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:2632
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2413
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 2371 of file xml.c.

2372 {
2374  const char *p;
2375 
2376  initStringInfo(&buf);
2377 
2378  for (p = name; *p; p += pg_mblen(p))
2379  {
2380  if (*p == '_' && *(p + 1) == 'x'
2381  && isxdigit((unsigned char) *(p + 2))
2382  && isxdigit((unsigned char) *(p + 3))
2383  && isxdigit((unsigned char) *(p + 4))
2384  && isxdigit((unsigned char) *(p + 5))
2385  && *(p + 6) == '_')
2386  {
2387  char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
2388  unsigned int u;
2389 
2390  sscanf(p + 2, "%X", &u);
2391  pg_unicode_to_server(u, (unsigned char *) cbuf);
2392  appendStringInfoString(&buf, cbuf);
2393  p += 6;
2394  }
2395  else
2397  }
2398 
2399  return buf.data;
2400 }
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:864
#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 2721 of file xml.c.

2722 {
2723  uint64 i;
2724  List *list = NIL;
2725  int spi_result;
2726 
2727  spi_result = SPI_execute(query, true, 0);
2728  if (spi_result != SPI_OK_SELECT)
2729  elog(ERROR, "SPI_execute returned %s for %s",
2730  SPI_result_code_string(spi_result), query);
2731 
2732  for (i = 0; i < SPI_processed; i++)
2733  {
2734  Datum oid;
2735  bool isnull;
2736 
2737  oid = SPI_getbinval(SPI_tuptable->vals[i],
2739  1,
2740  &isnull);
2741  if (!isnull)
2743  }
2744 
2745  return list;
2746 }
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
SPITupleTable * SPI_tuptable
Definition: spi.c:45
const char * SPI_result_code_string(int code)
Definition: spi.c:1969
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:593
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1249
#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 2834 of file xml.c.

2835 {
2836  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2837  bool nulls = PG_GETARG_BOOL(1);
2838  bool tableforest = PG_GETARG_BOOL(2);
2839  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2840 
2842  NULL, nulls, tableforest,
2843  targetns, true)));
2844 }
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:2936

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

3081 {
3082  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3083  bool nulls = PG_GETARG_BOOL(1);
3084  bool tableforest = PG_GETARG_BOOL(2);
3085  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3086 
3087  const char *xmlschema;
3088  SPIPlanPtr plan;
3089  Portal portal;
3090 
3091  SPI_connect();
3092 
3093  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3094  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3095 
3096  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3097  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3098 
3099  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
3100  InvalidOid, nulls, tableforest, targetns));
3101  SPI_cursor_close(portal);
3102  SPI_finish();
3103 
3105  xmlschema, nulls, tableforest,
3106  targetns, true)));
3107 }
#define plan(x)
Definition: pg_regress.c:162
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1442
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:857
void SPI_cursor_close(Portal portal)
Definition: spi.c:1859

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

2939 {
2940  StringInfo result;
2941  char *xmltn;
2942  uint64 i;
2943 
2944  if (tablename)
2945  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2946  else
2947  xmltn = "table";
2948 
2949  result = makeStringInfo();
2950 
2951  SPI_connect();
2952  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2953  ereport(ERROR,
2954  (errcode(ERRCODE_DATA_EXCEPTION),
2955  errmsg("invalid query")));
2956 
2957  if (!tableforest)
2958  {
2959  xmldata_root_element_start(result, xmltn, xmlschema,
2960  targetns, top_level);
2961  appendStringInfoChar(result, '\n');
2962  }
2963 
2964  if (xmlschema)
2965  appendStringInfo(result, "%s\n\n", xmlschema);
2966 
2967  for (i = 0; i < SPI_processed; i++)
2968  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2969  tableforest, targetns, top_level);
2970 
2971  if (!tableforest)
2972  xmldata_root_element_end(result, xmltn);
2973 
2974  SPI_finish();
2975 
2976  return result;
2977 }

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

3001 {
3002  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
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 *result;
3007  SPIPlanPtr plan;
3008  Portal portal;
3009 
3010  SPI_connect();
3011 
3012  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3013  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3014 
3015  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3016  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3017 
3019  InvalidOid, nulls,
3020  tableforest, targetns));
3021  SPI_cursor_close(portal);
3022  SPI_finish();
3023 
3025 }

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

2751 {
2752  StringInfoData query;
2753 
2754  initStringInfo(&query);
2755  appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2756  " WHERE relnamespace = %u AND relkind IN ("
2757  CppAsString2(RELKIND_RELATION) ","
2758  CppAsString2(RELKIND_MATVIEW) ","
2759  CppAsString2(RELKIND_VIEW) ")"
2760  " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2761  " ORDER BY relname;", nspid);
2762 
2763  return query_to_oid_list(query.data);
2764 }

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

3160 {
3161  Name name = PG_GETARG_NAME(0);
3162  bool nulls = PG_GETARG_BOOL(1);
3163  bool tableforest = PG_GETARG_BOOL(2);
3164  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3165 
3166  char *schemaname;
3167  Oid nspid;
3168 
3169  schemaname = NameStr(*name);
3170  nspid = LookupExplicitNamespace(schemaname, false);
3171 
3173  nulls, tableforest, targetns, true)));
3174 }
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3370
Definition: c.h:728

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

3264 {
3265  Name name = PG_GETARG_NAME(0);
3266  bool nulls = PG_GETARG_BOOL(1);
3267  bool tableforest = PG_GETARG_BOOL(2);
3268  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3269  char *schemaname;
3270  Oid nspid;
3271  StringInfo xmlschema;
3272 
3273  schemaname = NameStr(*name);
3274  nspid = LookupExplicitNamespace(schemaname, false);
3275 
3276  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3277  tableforest, targetns);
3278 
3280  xmlschema->data, nulls,
3281  tableforest, targetns, true)));
3282 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3205

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

3118 {
3119  StringInfo result;
3120  char *xmlsn;
3121  List *relid_list;
3122  ListCell *cell;
3123 
3125  true, false);
3126  result = makeStringInfo();
3127 
3128  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
3129  appendStringInfoChar(result, '\n');
3130 
3131  if (xmlschema)
3132  appendStringInfo(result, "%s\n\n", xmlschema);
3133 
3134  SPI_connect();
3135 
3136  relid_list = schema_get_xml_visible_tables(nspid);
3137 
3138  foreach(cell, relid_list)
3139  {
3140  Oid relid = lfirst_oid(cell);
3141  StringInfo subres;
3142 
3143  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
3144  targetns, false);
3145 
3146  appendBinaryStringInfo(result, subres->data, subres->len);
3147  appendStringInfoChar(result, '\n');
3148  }
3149 
3150  SPI_finish();
3151 
3152  xmldata_root_element_end(result, xmlsn);
3153 
3154  return result;
3155 }
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2750
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2803

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

3251 {
3252  Name name = PG_GETARG_NAME(0);
3253  bool nulls = PG_GETARG_BOOL(1);
3254  bool tableforest = PG_GETARG_BOOL(2);
3255  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3256 
3258  nulls, tableforest, targetns)));
3259 }

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

3207 {
3208  Oid nspid;
3209  List *relid_list;
3210  List *tupdesc_list;
3211  ListCell *cell;
3212  StringInfo result;
3213 
3214  result = makeStringInfo();
3215 
3216  nspid = LookupExplicitNamespace(schemaname, false);
3217 
3218  xsd_schema_element_start(result, targetns);
3219 
3220  SPI_connect();
3221 
3222  relid_list = schema_get_xml_visible_tables(nspid);
3223 
3224  tupdesc_list = NIL;
3225  foreach(cell, relid_list)
3226  {
3227  Relation rel;
3228 
3229  rel = table_open(lfirst_oid(cell), AccessShareLock);
3230  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3231  table_close(rel, NoLock);
3232  }
3233 
3234  appendStringInfoString(result,
3235  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3236 
3237  appendStringInfoString(result,
3239  nulls, tableforest, targetns));
3240 
3241  xsd_schema_element_end(result);
3242 
3243  SPI_finish();
3244 
3245  return result;
3246 }
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3556

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

4024 {
4025  int i;
4026  char *xmltn;
4027 
4028  if (tablename)
4029  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
4030  else
4031  {
4032  if (tableforest)
4033  xmltn = "row";
4034  else
4035  xmltn = "table";
4036  }
4037 
4038  if (tableforest)
4039  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
4040  else
4041  appendStringInfoString(result, "<row>\n");
4042 
4043  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
4044  {
4045  char *colname;
4046  Datum colval;
4047  bool isnull;
4048 
4050  true, false);
4051  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
4053  i,
4054  &isnull);
4055  if (isnull)
4056  {
4057  if (nulls)
4058  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
4059  }
4060  else
4061  appendStringInfo(result, " <%s>%s</%s>\n",
4062  colname,
4064  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
4065  colname);
4066  }
4067 
4068  if (tableforest)
4069  {
4070  xmldata_root_element_end(result, xmltn);
4071  appendStringInfoChar(result, '\n');
4072  }
4073  else
4074  appendStringInfoString(result, "</row>\n\n");
4075 }
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1305
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1195

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

2821 {
2822  Oid relid = PG_GETARG_OID(0);
2823  bool nulls = PG_GETARG_BOOL(1);
2824  bool tableforest = PG_GETARG_BOOL(2);
2825  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2826 
2828  nulls, tableforest,
2829  targetns, true)));
2830 }
#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 3059 of file xml.c.

3060 {
3061  Oid relid = PG_GETARG_OID(0);
3062  bool nulls = PG_GETARG_BOOL(1);
3063  bool tableforest = PG_GETARG_BOOL(2);
3064  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3065  Relation rel;
3066  const char *xmlschema;
3067 
3068  rel = table_open(relid, AccessShareLock);
3069  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3070  tableforest, targetns);
3071  table_close(rel, NoLock);
3072 
3074  xmlschema, nulls, tableforest,
3075  targetns, true)));
3076 }

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

2806 {
2807  StringInfoData query;
2808 
2809  initStringInfo(&query);
2810  appendStringInfo(&query, "SELECT * FROM %s",
2812  ObjectIdGetDatum(relid))));
2813  return query_to_xml_internal(query.data, get_rel_name(relid),
2814  xmlschema, nulls, tableforest,
2815  targetns, top_level);
2816 }
#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 2981 of file xml.c.

2982 {
2983  Oid relid = PG_GETARG_OID(0);
2984  bool nulls = PG_GETARG_BOOL(1);
2985  bool tableforest = PG_GETARG_BOOL(2);
2986  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2987  const char *result;
2988  Relation rel;
2989 
2990  rel = table_open(relid, AccessShareLock);
2991  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2992  tableforest, targetns);
2993  table_close(rel, NoLock);
2994 
2996 }

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

638 {
640 
642 }
const void * data
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:960
int xmloption
Definition: xml.c:110

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

◆ xml_in()

Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 273 of file xml.c.

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

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

1097 {
1098 #ifdef USE_LIBXML
1099  xmlDocPtr doc;
1100  ErrorSaveContext escontext = {T_ErrorSaveContext};
1101 
1102  /*
1103  * We'll report "true" if no soft error is reported by xml_parse().
1104  */
1105  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
1106  GetDatabaseEncoding(), NULL, NULL, (Node *) &escontext);
1107  if (doc)
1108  xmlFreeDoc(doc);
1109 
1110  return !escontext.error_occurred;
1111 #else /* not USE_LIBXML */
1112  NO_XML_SUPPORT();
1113  return false;
1114 #endif /* not USE_LIBXML */
1115 }
void * arg
@ XMLOPTION_DOCUMENT
Definition: primnodes.h:1548
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 4538 of file xml.c.

4539 {
4540 #ifdef USE_LIBXML
4541  text *data = PG_GETARG_TEXT_PP(0);
4542 
4543  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4544 #else
4545  NO_XML_SUPPORT();
4546  return 0;
4547 #endif /* not USE_LIBXML */
4548 }
#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 4564 of file xml.c.

4565 {
4566 #ifdef USE_LIBXML
4567  text *data = PG_GETARG_TEXT_PP(0);
4568 
4569  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4570 #else
4571  NO_XML_SUPPORT();
4572  return 0;
4573 #endif /* not USE_LIBXML */
4574 }
@ XMLOPTION_CONTENT
Definition: primnodes.h:1549

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

4552 {
4553 #ifdef USE_LIBXML
4554  text *data = PG_GETARG_TEXT_PP(0);
4555 
4556  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4557 #else
4558  NO_XML_SUPPORT();
4559  return 0;
4560 #endif /* not USE_LIBXML */
4561 }

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

357 {
358  xmltype *x = PG_GETARG_XML_P(0);
359 
360  /*
361  * xml_out removes the encoding property in all cases. This is because we
362  * cannot control from here whether the datum will be converted to a
363  * different client encoding, so we'd do more harm than good by including
364  * it.
365  */
367 }
#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:312
#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 312 of file xml.c.

313 {
314  char *str = text_to_cstring((text *) x);
315 
316 #ifdef USE_LIBXML
317  size_t len = strlen(str);
318  xmlChar *version;
319  int standalone;
320  int res_code;
321 
322  if ((res_code = parse_xml_decl((xmlChar *) str,
323  &len, &version, NULL, &standalone)) == 0)
324  {
326 
328 
329  if (!print_xml_decl(&buf, version, target_encoding, standalone))
330  {
331  /*
332  * If we are not going to produce an XML declaration, eat a single
333  * newline in the original string to prevent empty first lines in
334  * the output.
335  */
336  if (*(str + len) == '\n')
337  len += 1;
338  }
340 
341  pfree(str);
342 
343  return buf.data;
344  }
345 
347  errcode(ERRCODE_INTERNAL_ERROR),
348  errmsg_internal("could not parse XML declaration in stored value"),
349  errdetail_for_xml_code(res_code));
350 #endif
351  return str;
352 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
#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 371 of file xml.c.

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

439 {
440  xmltype *x = PG_GETARG_XML_P(0);
441  char *outval;
443 
444  /*
445  * xml_out_internal doesn't convert the encoding, it just prints the right
446  * declaration. pq_sendtext will do the conversion.
447  */
449 
451  pq_sendtext(&buf, outval, strlen(outval));
452  pfree(outval);
454 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
int pg_get_client_encoding(void)
Definition: mbutils.c:336
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346

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

492 {
493 #ifdef USE_LIBXML
494  text *arg = PG_GETARG_TEXT_PP(0);
495  char *argdata = VARDATA_ANY(arg);
496  int len = VARSIZE_ANY_EXHDR(arg);
498  int i;
499 
500  /* check for "--" in string or "-" at the end */
501  for (i = 1; i < len; i++)
502  {
503  if (argdata[i] == '-' && argdata[i - 1] == '-')
504  ereport(ERROR,
505  (errcode(ERRCODE_INVALID_XML_COMMENT),
506  errmsg("invalid XML comment")));
507  }
508  if (len > 0 && argdata[len - 1] == '-')
509  ereport(ERROR,
510  (errcode(ERRCODE_INVALID_XML_COMMENT),
511  errmsg("invalid XML comment")));
512 
514  appendStringInfoString(&buf, "<!--");
516  appendStringInfoString(&buf, "-->");
517 
519 #else
520  NO_XML_SUPPORT();
521  return 0;
522 #endif
523 }
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3981

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

554 {
555 #ifdef USE_LIBXML
556  int global_standalone = 1;
557  xmlChar *global_version = NULL;
558  bool global_version_no_value = false;
560  ListCell *v;
561 
563  foreach(v, args)
564  {
566  size_t len;
567  xmlChar *version;
568  int standalone;
569  char *str;
570 
571  len = VARSIZE(x) - VARHDRSZ;
572  str = text_to_cstring((text *) x);
573 
574  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
575 
576  if (standalone == 0 && global_standalone == 1)
577  global_standalone = 0;
578  if (standalone < 0)
579  global_standalone = -1;
580 
581  if (!version)
582  global_version_no_value = true;
583  else if (!global_version)
584  global_version = version;
585  else if (xmlStrcmp(version, global_version) != 0)
586  global_version_no_value = true;
587 
589  pfree(str);
590  }
591 
592  if (!global_version_no_value || global_standalone >= 0)
593  {
594  StringInfoData buf2;
595 
596  initStringInfo(&buf2);
597 
598  print_xml_decl(&buf2,
599  (!global_version_no_value) ? global_version : NULL,
600  0,
601  global_standalone);
602 
603  appendBinaryStringInfo(&buf2, buf.data, buf.len);
604  buf = buf2;
605  }
606 
607  return stringinfo_to_xmltype(&buf);
608 #else
609  NO_XML_SUPPORT();
610  return NULL;
611 #endif
612 }
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 619 of file xml.c.

620 {
621  if (PG_ARGISNULL(0))
622  {
623  if (PG_ARGISNULL(1))
624  PG_RETURN_NULL();
625  else
627  }
628  else if (PG_ARGISNULL(1))
630  else
632  PG_GETARG_XML_P(1))));
633 }
#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:553

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

2930 {
2931  appendStringInfo(result, "</%s>\n", eltname);
2932 }

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

2905 {
2906  /* This isn't really wrong but currently makes no sense. */
2907  Assert(top_level || !xmlschema);
2908 
2909  appendStringInfo(result, "<%s", eltname);
2910  if (top_level)
2911  {
2912  appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2913  if (strlen(targetns) > 0)
2914  appendStringInfo(result, " xmlns=\"%s\"", targetns);
2915  }
2916  if (xmlschema)
2917  {
2918  /* FIXME: better targets */
2919  if (strlen(targetns) > 0)
2920  appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2921  else
2922  appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2923  }
2924  appendStringInfoString(result, ">\n");
2925 }
#define NAMESPACE_XSI
Definition: xml.c:244

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

839 {
840 #ifdef USE_LIBXML
841  xmltype *result;
842  List *named_arg_strings;
843  List *arg_strings;
844  int i;
845  ListCell *arg;
846  ListCell *narg;
847  PgXmlErrorContext *xmlerrcxt;
848  volatile xmlBufferPtr buf = NULL;
849  volatile xmlTextWriterPtr writer = NULL;
850 
851  /*
852  * All arguments are already evaluated, and their values are passed in the
853  * named_argvalue/named_argnull or argvalue/argnull arrays. This avoids
854  * issues if one of the arguments involves a call to some other function
855  * or subsystem that wants to use libxml on its own terms. We examine the
856  * original XmlExpr to identify the numbers and types of the arguments.
857  */
858  named_arg_strings = NIL;
859  i = 0;
860  foreach(arg, xexpr->named_args)
861  {
862  Expr *e = (Expr *) lfirst(arg);
863  char *str;
864 
865  if (named_argnull[i])
866  str = NULL;
867  else
868  str = map_sql_value_to_xml_value(named_argvalue[i],
869  exprType((Node *) e),
870  false);
871  named_arg_strings = lappend(named_arg_strings, str);
872  i++;
873  }
874 
875  arg_strings = NIL;
876  i = 0;
877  foreach(arg, xexpr->args)
878  {
879  Expr *e = (Expr *) lfirst(arg);
880  char *str;
881 
882  /* here we can just forget NULL elements immediately */
883  if (!argnull[i])
884  {
885  str = map_sql_value_to_xml_value(argvalue[i],
886  exprType((Node *) e),
887  true);
888  arg_strings = lappend(arg_strings, str);
889  }
890  i++;
891  }
892 
893  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
894 
895  PG_TRY();
896  {
897  buf = xmlBufferCreate();
898  if (buf == NULL || xmlerrcxt->err_occurred)
899  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
900  "could not allocate xmlBuffer");
901  writer = xmlNewTextWriterMemory(buf, 0);
902  if (writer == NULL || xmlerrcxt->err_occurred)
903  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
904  "could not allocate xmlTextWriter");
905 
906  xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
907 
908  forboth(arg, named_arg_strings, narg, xexpr->arg_names)
909  {
910  char *str = (char *) lfirst(arg);
911  char *argname = strVal(lfirst(narg));
912 
913  if (str)
914  xmlTextWriterWriteAttribute(writer,
915  (xmlChar *) argname,
916  (xmlChar *) str);
917  }
918 
919  foreach(arg, arg_strings)
920  {
921  char *str = (char *) lfirst(arg);
922 
923  xmlTextWriterWriteRaw(writer, (xmlChar *) str);
924  }
925 
926  xmlTextWriterEndElement(writer);
927 
928  /* we MUST do this now to flush data out to the buffer ... */
929  xmlFreeTextWriter(writer);
930  writer = NULL;
931 
932  result = xmlBuffer_to_xmltype(buf);
933  }
934  PG_CATCH();
935  {
936  if (writer)
937  xmlFreeTextWriter(writer);
938  if (buf)
939  xmlBufferFree(buf);
940 
941  pg_xml_done(xmlerrcxt, true);
942 
943  PG_RE_THROW();
944  }
945  PG_END_TRY();
946 
947  xmlBufferFree(buf);
948 
949  pg_xml_done(xmlerrcxt, false);
950 
951  return result;
952 #else
953  NO_XML_SUPPORT();
954  return NULL;
955 #endif
956 }
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
e
Definition: preproc-init.c:82
List * args
Definition: primnodes.h:1564
List * named_args
Definition: primnodes.h:1560
#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 4473 of file xml.c.

4474 {
4475 #ifdef USE_LIBXML
4476  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4478  int res_nitems;
4479 
4480  xpath_internal(xpath_expr_text, data, NULL,
4481  &res_nitems, NULL);
4482 
4483  PG_RETURN_BOOL(res_nitems > 0);
4484 #else
4485  NO_XML_SUPPORT();
4486  return 0;
4487 #endif
4488 }

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

961 {
962 #ifdef USE_LIBXML
963  xmlDocPtr doc;
964 
965  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
966  GetDatabaseEncoding(), NULL, NULL, NULL);
967  xmlFreeDoc(doc);
968 
969  return (xmltype *) data;
970 #else
971  NO_XML_SUPPORT();
972  return NULL;
973 #endif
974 }

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

979 {
980 #ifdef USE_LIBXML
981  xmltype *result;
983 
984  if (pg_strcasecmp(target, "xml") == 0)
985  ereport(ERROR,
986  (errcode(ERRCODE_SYNTAX_ERROR), /* really */
987  errmsg("invalid XML processing instruction"),
988  errdetail("XML processing instruction target name cannot be \"%s\".", target)));
989 
990  /*
991  * Following the SQL standard, the null check comes after the syntax check
992  * above.
993  */
994  *result_is_null = arg_is_null;
995  if (*result_is_null)
996  return NULL;
997 
999 
1000  appendStringInfo(&buf, "<?%s", target);
1001 
1002  if (arg != NULL)
1003  {
1004  char *string;
1005 
1006  string = text_to_cstring(arg);
1007  if (strstr(string, "?>") != NULL)
1008  ereport(ERROR,
1009  (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
1010  errmsg("invalid XML processing instruction"),
1011  errdetail("XML processing instruction cannot contain \"?>\".")));
1012 
1013  appendStringInfoChar(&buf, ' ');
1014  appendStringInfoString(&buf, string + strspn(string, " "));
1015  pfree(string);
1016  }
1017  appendStringInfoString(&buf, "?>");
1018 
1019  result = stringinfo_to_xmltype(&buf);
1020  pfree(buf.data);
1021  return result;
1022 #else
1023  NO_XML_SUPPORT();
1024  return NULL;
1025 #endif
1026 }
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 1030 of file xml.c.

1031 {
1032 #ifdef USE_LIBXML
1033  char *str;
1034  size_t len;
1035  xmlChar *orig_version;
1036  int orig_standalone;
1038 
1039  len = VARSIZE(data) - VARHDRSZ;
1040  str = text_to_cstring((text *) data);
1041 
1042  parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
1043 
1044  if (version)
1045  orig_version = xml_text2xmlChar(version);
1046  else
1047  orig_version = NULL;
1048 
1049  switch (standalone)
1050  {
1051  case XML_STANDALONE_YES:
1052  orig_standalone = 1;
1053  break;
1054  case XML_STANDALONE_NO:
1055  orig_standalone = 0;
1056  break;
1058  orig_standalone = -1;
1059  break;
1061  /* leave original value */
1062  break;
1063  }
1064 
1065  initStringInfo(&buf);
1066  print_xml_decl(&buf, orig_version, 0, orig_standalone);
1068 
1069  return stringinfo_to_xmltype(&buf);
1070 #else
1071  NO_XML_SUPPORT();
1072  return NULL;
1073 #endif
1074 }
@ 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 5002 of file xml.c.

5003 {
5004 #ifdef USE_LIBXML
5005  XmlTableBuilderData *xtCxt;
5006 
5007  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
5008 
5009  /* Propagate our own error context to libxml2 */
5010  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
5011 
5012  if (xtCxt->xpathscomp != NULL)
5013  {
5014  int i;
5015 
5016  for (i = 0; i < xtCxt->natts; i++)
5017  if (xtCxt->xpathscomp[i] != NULL)
5018  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
5019  }
5020 
5021  if (xtCxt->xpathobj != NULL)
5022  xmlXPathFreeObject(xtCxt->xpathobj);
5023  if (xtCxt->xpathcomp != NULL)
5024  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
5025  if (xtCxt->xpathcxt != NULL)
5026  xmlXPathFreeContext(xtCxt->xpathcxt);
5027  if (xtCxt->doc != NULL)
5028  xmlFreeDoc(xtCxt->doc);
5029  if (xtCxt->ctxt != NULL)
5030  xmlFreeParserCtxt(xtCxt->ctxt);
5031 
5032  pg_xml_done(xtCxt->xmlerrcxt, true);
5033 
5034  /* not valid anymore */
5035  xtCxt->magic = 0;
5036  state->opaque = NULL;
5037 
5038 #else
5039  NO_XML_SUPPORT();
5040 #endif /* not USE_LIBXML */
5041 }
Definition: regguts.h:323

References i, NO_XML_SUPPORT, and pg_xml_done().

◆ XmlTableFetchRow()

static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4805 of file xml.c.

4806 {
4807 #ifdef USE_LIBXML
4808  XmlTableBuilderData *xtCxt;
4809 
4810  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4811 
4812  /* Propagate our own error context to libxml2 */
4813  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4814 
4815  if (xtCxt->xpathobj == NULL)
4816  {
4817  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4818  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4819  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4820  "could not create XPath object");
4821 
4822  xtCxt->row_count = 0;
4823  }
4824 
4825  if (xtCxt->xpathobj->type == XPATH_NODESET)
4826  {
4827  if (xtCxt->xpathobj->nodesetval != NULL)
4828  {
4829  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4830  return true;
4831  }
4832  }
4833 
4834  return false;
4835 #else
4836  NO_XML_SUPPORT();
4837  return false;
4838 #endif /* not USE_LIBXML */
4839 }

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

4852 {
4853 #ifdef USE_LIBXML
4854  XmlTableBuilderData *xtCxt;
4855  Datum result = (Datum) 0;
4856  xmlNodePtr cur;
4857  char *cstr = NULL;
4858  volatile xmlXPathObjectPtr xpathobj = NULL;
4859 
4860  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4861 
4862  Assert(xtCxt->xpathobj &&
4863  xtCxt->xpathobj->type == XPATH_NODESET &&
4864  xtCxt->xpathobj->nodesetval != NULL);
4865 
4866  /* Propagate our own error context to libxml2 */
4867  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4868 
4869  *isnull = false;
4870 
4871  cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
4872 
4873  Assert(xtCxt->xpathscomp[colnum] != NULL);
4874 
4875  PG_TRY();
4876  {
4877  /* Set current node as entry point for XPath evaluation */
4878  xtCxt->xpathcxt->node = cur;
4879 
4880  /* Evaluate column path */
4881  xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
4882  if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4883  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4884  "could not create XPath object");
4885 
4886  /*
4887  * There are four possible cases, depending on the number of nodes
4888  * returned by the XPath expression and the type of the target column:
4889  * a) XPath returns no nodes. b) The target type is XML (return all
4890  * as XML). For non-XML return types: c) One node (return content).
4891  * d) Multiple nodes (error).
4892  */
4893  if (xpathobj->type == XPATH_NODESET)
4894  {
4895  int count = 0;
4896 
4897  if (xpathobj->nodesetval != NULL)
4898  count = xpathobj->nodesetval->nodeNr;
4899 
4900  if (xpathobj->nodesetval == NULL || count == 0)
4901  {
4902  *isnull = true;
4903  }
4904  else
4905  {
4906  if (typid == XMLOID)
4907  {
4908  text *textstr;
4910 
4911  /* Concatenate serialized values */
4912  initStringInfo(&str);
4913  for (int i = 0; i < count; i++)
4914  {
4915  textstr =
4916  xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
4917  xtCxt->xmlerrcxt);
4918 
4919  appendStringInfoText(&str, textstr);
4920  }
4921  cstr = str.data;
4922  }
4923  else
4924  {
4925  xmlChar *str;
4926 
4927  if (count > 1)
4928  ereport(ERROR,
4929  (errcode(ERRCODE_CARDINALITY_VIOLATION),
4930  errmsg("more than one value returned by column XPath expression")));
4931 
4932  str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);
4933  cstr = str ? xml_pstrdup_and_free(str) : "";
4934  }
4935  }
4936  }
4937  else if (xpathobj->type == XPATH_STRING)
4938  {
4939  /* Content should be escaped when target will be XML */
4940  if (typid == XMLOID)
4941  cstr = escape_xml((char *) xpathobj->stringval);
4942  else
4943  cstr = (char *) xpathobj->stringval;
4944  }
4945  else if (xpathobj->type == XPATH_BOOLEAN)
4946  {
4947  char typcategory;
4948  bool typispreferred;
4949  xmlChar *str;
4950 
4951  /* Allow implicit casting from boolean to numbers */
4952  get_type_category_preferred(typid, &typcategory, &typispreferred);
4953 
4954  if (typcategory != TYPCATEGORY_NUMERIC)
4955  str = xmlXPathCastBooleanToString(xpathobj->boolval);
4956  else
4957  str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval));
4958 
4959  cstr = xml_pstrdup_and_free(str);
4960  }
4961  else if (xpathobj->type == XPATH_NUMBER)
4962  {
4963  xmlChar *str;
4964 
4965  str = xmlXPathCastNumberToString(xpathobj->floatval);
4966  cstr = xml_pstrdup_and_free(str);
4967  }
4968  else
4969  elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
4970 
4971  /*
4972  * By here, either cstr contains the result value, or the isnull flag
4973  * has been set.
4974  */
4975  Assert(cstr || *isnull);
4976 
4977  if (!*isnull)
4978  result = InputFunctionCall(&state->in_functions[colnum],
4979  cstr,
4980  state->typioparams[colnum],
4981  typmod);
4982  }
4983  PG_FINALLY();
4984  {
4985  if (xpathobj != NULL)
4986  xmlXPathFreeObject(xpathobj);
4987  }
4988  PG_END_TRY();
4989 
4990  return result;
4991 #else
4992  NO_XML_SUPPORT();
4993  return 0;
4994 #endif /* not USE_LIBXML */
4995 }
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:1530
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2666

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

4614 {
4615 #ifdef USE_LIBXML
4616  volatile xmlParserCtxtPtr ctxt = NULL;
4617  XmlTableBuilderData *xtCxt;
4618  PgXmlErrorContext *xmlerrcxt;
4619 
4620  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4621  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4622  xtCxt->natts = natts;
4623  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4624 
4625  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4626 
4627  PG_TRY();
4628  {
4629  xmlInitParser();
4630 
4631  ctxt = xmlNewParserCtxt();
4632  if (ctxt == NULL || xmlerrcxt->err_occurred)
4633  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4634  "could not allocate parser context");
4635  }
4636  PG_CATCH();
4637  {
4638  if (ctxt != NULL)
4639  xmlFreeParserCtxt(ctxt);
4640 
4641  pg_xml_done(xmlerrcxt, true);
4642 
4643  PG_RE_THROW();
4644  }
4645  PG_END_TRY();
4646 
4647  xtCxt->xmlerrcxt = xmlerrcxt;
4648  xtCxt->ctxt = ctxt;
4649 
4650  state->opaque = xtCxt;
4651 #else
4652  NO_XML_SUPPORT();
4653 #endif /* not USE_LIBXML */
4654 }
void * palloc0(Size size)
Definition: mcxt.c:1334

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

4774 {
4775 #ifdef USE_LIBXML
4776  XmlTableBuilderData *xtCxt;
4777  xmlChar *xstr;
4778 
4779  Assert(PointerIsValid(path));
4780 
4781  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4782 
4783  if (*path == '\0')
4784  ereport(ERROR,
4785  (errcode(ERRCODE_DATA_EXCEPTION),
4786  errmsg("column path filter must not be empty string")));
4787 
4788  xstr = pg_xmlCharStrndup(path, strlen(path));
4789 
4790  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4791  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4792  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4793  "invalid XPath expression");
4794 #else
4795  NO_XML_SUPPORT();
4796 #endif /* not USE_LIBXML */
4797 }
#define PointerIsValid(pointer)
Definition: c.h:750

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

4662 {
4663 #ifdef USE_LIBXML
4664  XmlTableBuilderData *xtCxt;
4665  xmltype *xmlval = DatumGetXmlP(value);
4666  char *str;
4667  xmlChar *xstr;
4668  int length;
4669  volatile xmlDocPtr doc = NULL;
4670  volatile xmlXPathContextPtr xpathcxt = NULL;
4671 
4672  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4673 
4674  /*
4675  * Use out function for casting to string (remove encoding property). See
4676  * comment in xml_out.
4677  */
4678  str = xml_out_internal(xmlval, 0);
4679 
4680  length = strlen(str);
4681  xstr = pg_xmlCharStrndup(str, length);
4682 
4683  PG_TRY();
4684  {
4685  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4686  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4687  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4688  "could not parse XML document");
4689  xpathcxt = xmlXPathNewContext(doc);
4690  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4691  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4692  "could not allocate XPath context");
4693  xpathcxt->node = (xmlNodePtr) doc;
4694  }
4695  PG_CATCH();
4696  {
4697  if (xpathcxt != NULL)
4698  xmlXPathFreeContext(xpathcxt);
4699  if (doc != NULL)
4700  xmlFreeDoc(doc);
4701 
4702  PG_RE_THROW();
4703  }
4704  PG_END_TRY();
4705 
4706  xtCxt->doc = doc;
4707  xtCxt->xpathcxt = xpathcxt;
4708 #else
4709  NO_XML_SUPPORT();
4710 #endif /* not USE_LIBXML */
4711 }

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

4719 {
4720 #ifdef USE_LIBXML
4721  XmlTableBuilderData *xtCxt;
4722 
4723  if (name == NULL)
4724  ereport(ERROR,
4725  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4726  errmsg("DEFAULT namespace is not supported")));
4727  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4728 
4729  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4730  pg_xmlCharStrndup(name, strlen(name)),
4731  pg_xmlCharStrndup(uri, strlen(uri))))
4732  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4733  "could not set XML namespace");
4734 #else
4735  NO_XML_SUPPORT();
4736 #endif /* not USE_LIBXML */
4737 }

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

4745 {
4746 #ifdef USE_LIBXML
4747  XmlTableBuilderData *xtCxt;
4748  xmlChar *xstr;
4749 
4750  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4751 
4752  if (*path == '\0')
4753  ereport(ERROR,
4754  (errcode(ERRCODE_DATA_EXCEPTION),
4755  errmsg("row path filter must not be empty string")));
4756 
4757  xstr = pg_xmlCharStrndup(path, strlen(path));
4758 
4759  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4760  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4761  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4762  "invalid XPath expression");
4763 #else
4764  NO_XML_SUPPORT();
4765 #endif /* not USE_LIBXML */
4766 }

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

◆ xmltext()

Datum xmltext ( PG_FUNCTION_ARGS  )

Definition at line 527 of file xml.c.

528 {
529 #ifdef USE_LIBXML
530  text *arg = PG_GETARG_TEXT_PP(0);
531  text *result;
532  xmlChar *xmlbuf = NULL;
533 
534  xmlbuf = xmlEncodeSpecialChars(NULL, xml_text2xmlChar(arg));
535 
536  Assert(xmlbuf);
537 
538  result = cstring_to_text_with_len((const char *) xmlbuf, xmlStrlen(xmlbuf));
539  xmlFree(xmlbuf);
540  PG_RETURN_XML_P(result);
541 #else
542  NO_XML_SUPPORT();
543  return 0;
544 #endif /* not USE_LIBXML */
545 }

References arg, Assert(), cstring_to_text_with_len(), NO_XML_SUPPORT, PG_GETARG_TEXT_PP, and PG_RETURN_XML_P.

◆ xmltotext()

Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 646 of file xml.c.

647 {
649 
650  /* It's actually binary compatible. */
652 }
#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 656 of file xml.c.

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

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

1087 {
1088  ereport(ERROR,
1089  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1090  errmsg("xmlvalidate is not implemented")));
1091  return 0;
1092 }

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

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4450 of file xml.c.

4451 {
4452 #ifdef USE_LIBXML
4453  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4455  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4456  ArrayBuildState *astate;
4457 
4458  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4459  xpath_internal(xpath_expr_text, data, namespaces,
4460  NULL, astate);
4462 #else
4463  NO_XML_SUPPORT();
4464  return 0;
4465 #endif
4466 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5274
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5401
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
MemoryContext CurrentMemoryContext
Definition: mcxt.c:131

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

4497 {
4498 #ifdef USE_LIBXML
4499  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4501  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4502  int res_nitems;
4503 
4504  xpath_internal(xpath_expr_text, data, namespaces,
4505  &res_nitems, NULL);
4506 
4507  PG_RETURN_BOOL(res_nitems > 0);
4508 #else
4509  NO_XML_SUPPORT();
4510  return 0;
4511 #endif
4512 }

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

3199 {
3200  appendStringInfoString(result, "</xsd:schema>");
3201 }

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

3182 {
3183  appendStringInfoString(result,
3184  "<xsd:schema\n"
3185  " xmlns:xsd=\"" NAMESPACE_XSD "\"");
3186  if (strlen(targetns) > 0)
3187  appendStringInfo(result,
3188  "\n"
3189  " targetNamespace=\"%s\"\n"
3190  " elementFormDefault=\"qualified\"",
3191  targetns);
3192  appendStringInfoString(result,
3193  ">\n\n");
3194 }
#define NAMESPACE_XSD
Definition: xml.c:243

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

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

◆ XmlTableRoutine

const TableFuncRoutine XmlTableRoutine
Initial value:
=
{
.InitOpaque = XmlTableInitOpaque,
.SetDocument = XmlTableSetDocument,
.SetNamespace = XmlTableSetNamespace,
.SetRowFilter = XmlTableSetRowFilter,
.SetColumnFilter = XmlTableSetColumnFilter,
.FetchRow = XmlTableFetchRow,
.GetValue = XmlTableGetValue,
.DestroyOpaque = XmlTableDestroyOpaque
}
static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts)
Definition: xml.c:4613
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4718
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4744
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4850
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4661
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:5002
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4805
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4773

Definition at line 223 of file xml.c.

Referenced by ExecInitTableFuncScan().