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/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xml.h"
Include dependency graph for xml.c:

Go to the source code of this file.

Macros

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

Functions

static void xmldata_root_element_start (StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
 
static void xmldata_root_element_end (StringInfo result, const char *eltname)
 
static StringInfo query_to_xml_internal (const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static const char * map_sql_table_to_xmlschema (TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_schema_to_xmlschema_types (Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_catalog_to_xmlschema_types (List *nspid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_type_to_xml_name (Oid typeoid, int typmod)
 
static const char * map_sql_typecoll_to_xmlschema_types (List *tupdesc_list)
 
static const char * map_sql_type_to_xmlschema_type (Oid typeoid, int typmod)
 
static void SPI_sql_row_to_xmlelement (uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static void XmlTableInitOpaque (struct TableFuncScanState *state, int natts)
 
static void XmlTableSetDocument (struct TableFuncScanState *state, Datum value)
 
static void XmlTableSetNamespace (struct TableFuncScanState *state, const char *name, const char *uri)
 
static void XmlTableSetRowFilter (struct TableFuncScanState *state, const char *path)
 
static void XmlTableSetColumnFilter (struct TableFuncScanState *state, const char *path, int colnum)
 
static bool XmlTableFetchRow (struct TableFuncScanState *state)
 
static Datum XmlTableGetValue (struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
 
static void XmlTableDestroyOpaque (struct TableFuncScanState *state)
 
Datum xml_in (PG_FUNCTION_ARGS)
 
static char * xml_out_internal (xmltype *x, pg_enc target_encoding)
 
Datum xml_out (PG_FUNCTION_ARGS)
 
Datum xml_recv (PG_FUNCTION_ARGS)
 
Datum xml_send (PG_FUNCTION_ARGS)
 
static xmltypestringinfo_to_xmltype (StringInfo buf)
 
static xmltypecstring_to_xmltype (const char *string)
 
Datum xmlcomment (PG_FUNCTION_ARGS)
 
xmltypexmlconcat (List *args)
 
Datum xmlconcat2 (PG_FUNCTION_ARGS)
 
Datum texttoxml (PG_FUNCTION_ARGS)
 
Datum xmltotext (PG_FUNCTION_ARGS)
 
textxmltotext_with_xmloption (xmltype *data, XmlOptionType xmloption_arg)
 
xmltypexmlelement (XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
 
xmltypexmlparse (text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
 
xmltypexmlpi (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)
 
static char * unicode_to_sqlchar (pg_wchar c)
 
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
 
int xmloption
 
const TableFuncRoutine XmlTableRoutine
 

Macro Definition Documentation

◆ NAMESPACE_SQLXML

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

Definition at line 230 of file xml.c.

◆ NAMESPACE_XSD

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

Definition at line 228 of file xml.c.

Referenced by xsd_schema_element_start().

◆ NAMESPACE_XSI

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

Definition at line 229 of file xml.c.

Referenced by xmldata_root_element_start().

◆ 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."), \
errhint("You need to rebuild PostgreSQL using --with-libxml.")))
int errhint(const char *fmt,...)
Definition: elog.c:1069
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:955
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

Definition at line 219 of file xml.c.

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

◆ PG_XML_DEFAULT_VERSION

#define PG_XML_DEFAULT_VERSION   "1.0"

Definition at line 282 of file xml.c.

Referenced by xml_is_document().

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

Referenced by database_get_xml_visible_schemas(), and database_get_xml_visible_tables().

◆ XML_VISIBLE_SCHEMAS_EXCLUDE

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

Definition at line 2510 of file xml.c.

Function Documentation

◆ _SPI_strdup()

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2403 of file xml.c.

References SPI_palloc().

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

2404 {
2405  size_t len = strlen(s) + 1;
2406  char *ret = SPI_palloc(len);
2407 
2408  memcpy(ret, s, len);
2409  return ret;
2410 }
void * SPI_palloc(Size size)
Definition: spi.c:1114

◆ cstring_to_xmltype()

static xmltype* cstring_to_xmltype ( const char *  string)
static

Definition at line 454 of file xml.c.

References cstring_to_text(), and cstring_to_text_with_len().

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

455 {
456  return (xmltype *) cstring_to_text(string);
457 }
text * cstring_to_text(const char *s)
Definition: varlena.c:171
Definition: c.h:556

◆ cursor_to_xml()

Datum cursor_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2587 of file xml.c.

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

2588 {
2591  bool nulls = PG_GETARG_BOOL(2);
2592  bool tableforest = PG_GETARG_BOOL(3);
2593  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2594 
2595  StringInfoData result;
2596  Portal portal;
2597  uint64 i;
2598 
2599  initStringInfo(&result);
2600 
2601  if (!tableforest)
2602  {
2603  xmldata_root_element_start(&result, "table", NULL, targetns, true);
2604  appendStringInfoChar(&result, '\n');
2605  }
2606 
2607  SPI_connect();
2608  portal = SPI_cursor_find(name);
2609  if (portal == NULL)
2610  ereport(ERROR,
2611  (errcode(ERRCODE_UNDEFINED_CURSOR),
2612  errmsg("cursor \"%s\" does not exist", name)));
2613 
2614  SPI_cursor_fetch(portal, true, count);
2615  for (i = 0; i < SPI_processed; i++)
2616  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2617  tableforest, targetns, true);
2618 
2619  SPI_finish();
2620 
2621  if (!tableforest)
2622  xmldata_root_element_end(&result, "table");
2623 
2625 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2641
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
uint64 SPI_processed
Definition: spi.c:45
signed int int32
Definition: c.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1527
#define ERROR
Definition: elog.h:43
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2668
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:822
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
int i
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1539
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:3756

◆ cursor_to_xmlschema()

Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2768 of file xml.c.

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.

2769 {
2771  bool nulls = PG_GETARG_BOOL(1);
2772  bool tableforest = PG_GETARG_BOOL(2);
2773  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2774  const char *xmlschema;
2775  Portal portal;
2776 
2777  SPI_connect();
2778  portal = SPI_cursor_find(name);
2779  if (portal == NULL)
2780  ereport(ERROR,
2781  (errcode(ERRCODE_UNDEFINED_CURSOR),
2782  errmsg("cursor \"%s\" does not exist", name)));
2783 
2784  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2785  InvalidOid, nulls,
2786  tableforest, targetns));
2787  SPI_finish();
2788 
2789  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
2790 }
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1527
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2403
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3186
#define ereport(elevel, rest)
Definition: elog.h:141
TupleDesc tupDesc
Definition: portal.h:157
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:454
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ database_get_xml_visible_schemas()

static List* database_get_xml_visible_schemas ( void  )
static

Definition at line 2516 of file xml.c.

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

2517 {
2518  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2519 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2460
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2512

◆ database_get_xml_visible_tables()

static List* database_get_xml_visible_tables ( void  )
static

Definition at line 2523 of file xml.c.

References CppAsString2, query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xmlschema_internal().

2524 {
2525  /* At the moment there is no order required here. */
2526  return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2527  " WHERE relkind IN ("
2528  CppAsString2(RELKIND_RELATION) ","
2529  CppAsString2(RELKIND_MATVIEW) ","
2530  CppAsString2(RELKIND_VIEW) ")"
2531  " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2532  " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2533 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2460
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2512
#define CppAsString2(x)
Definition: c.h:224

◆ database_to_xml()

Datum database_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 3069 of file xml.c.

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

3070 {
3071  bool nulls = PG_GETARG_BOOL(0);
3072  bool tableforest = PG_GETARG_BOOL(1);
3073  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3074 
3076  tableforest, targetns)));
3077 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3026
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447

◆ database_to_xml_and_xmlschema()

Datum database_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3136 of file xml.c.

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

3137 {
3138  bool nulls = PG_GETARG_BOOL(0);
3139  bool tableforest = PG_GETARG_BOOL(1);
3140  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3141  StringInfo xmlschema;
3142 
3143  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3144 
3146  nulls, tableforest, targetns)));
3147 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3026
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3081
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447

◆ database_to_xml_internal()

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

Definition at line 3026 of file xml.c.

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

3028 {
3029  StringInfo result;
3030  List *nspid_list;
3031  ListCell *cell;
3032  char *xmlcn;
3033 
3035  true, false);
3036  result = makeStringInfo();
3037 
3038  xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
3039  appendStringInfoChar(result, '\n');
3040 
3041  if (xmlschema)
3042  appendStringInfo(result, "%s\n\n", xmlschema);
3043 
3044  SPI_connect();
3045 
3046  nspid_list = database_get_xml_visible_schemas();
3047 
3048  foreach(cell, nspid_list)
3049  {
3050  Oid nspid = lfirst_oid(cell);
3051  StringInfo subres;
3052 
3053  subres = schema_to_xml_internal(nspid, NULL, nulls,
3054  tableforest, targetns, false);
3055 
3056  appendBinaryStringInfo(result, subres->data, subres->len);
3057  appendStringInfoChar(result, '\n');
3058  }
3059 
3060  SPI_finish();
3061 
3062  xmldata_root_element_end(result, xmlcn);
3063 
3064  return result;
3065 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2641
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2851
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2516
Oid MyDatabaseId
Definition: globals.c:85
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2668
Definition: pg_list.h:50
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ database_to_xmlschema()

Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3124 of file xml.c.

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

3125 {
3126  bool nulls = PG_GETARG_BOOL(0);
3127  bool tableforest = PG_GETARG_BOOL(1);
3128  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3129 
3131  tableforest, targetns)));
3132 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3081
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447

◆ database_to_xmlschema_internal()

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

Definition at line 3081 of file xml.c.

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

3083 {
3084  List *relid_list;
3085  List *nspid_list;
3086  List *tupdesc_list;
3087  ListCell *cell;
3088  StringInfo result;
3089 
3090  result = makeStringInfo();
3091 
3092  xsd_schema_element_start(result, targetns);
3093 
3094  SPI_connect();
3095 
3096  relid_list = database_get_xml_visible_tables();
3097  nspid_list = database_get_xml_visible_schemas();
3098 
3099  tupdesc_list = NIL;
3100  foreach(cell, relid_list)
3101  {
3102  Relation rel;
3103 
3104  rel = table_open(lfirst_oid(cell), AccessShareLock);
3105  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3106  table_close(rel, NoLock);
3107  }
3108 
3109  appendStringInfoString(result,
3110  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3111 
3112  appendStringInfoString(result,
3113  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3114 
3115  xsd_schema_element_end(result);
3116 
3117  SPI_finish();
3118 
3119  return result;
3120 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2916
#define NIL
Definition: pg_list.h:65
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
#define AccessShareLock
Definition: lockdefs.h:36
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3364
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:322
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3526
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2516
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2933
TupleDesc rd_att
Definition: rel.h:84
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2523

◆ escape_xml()

char* escape_xml ( const char *  str)

Definition at line 2371 of file xml.c.

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

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

2372 {
2374  const char *p;
2375 
2376  initStringInfo(&buf);
2377  for (p = str; *p; p++)
2378  {
2379  switch (*p)
2380  {
2381  case '&':
2382  appendStringInfoString(&buf, "&amp;");
2383  break;
2384  case '<':
2385  appendStringInfoString(&buf, "&lt;");
2386  break;
2387  case '>':
2388  appendStringInfoString(&buf, "&gt;");
2389  break;
2390  case '\r':
2391  appendStringInfoString(&buf, "&#x0d;");
2392  break;
2393  default:
2394  appendStringInfoCharMacro(&buf, *p);
2395  break;
2396  }
2397  }
2398  return buf.data;
2399 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

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

3156 {
3157  StringInfoData result;
3158 
3159  initStringInfo(&result);
3160 
3161  if (a)
3162  appendStringInfoString(&result,
3163  map_sql_identifier_to_xml_name(a, true, true));
3164  if (b)
3165  appendStringInfo(&result, ".%s",
3166  map_sql_identifier_to_xml_name(b, true, true));
3167  if (c)
3168  appendStringInfo(&result, ".%s",
3169  map_sql_identifier_to_xml_name(c, true, true));
3170  if (d)
3171  appendStringInfo(&result, ".%s",
3172  map_sql_identifier_to_xml_name(d, true, true));
3173 
3174  return result.data;
3175 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * c
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

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

Referenced by database_to_xmlschema_internal().

3366 {
3367  char *dbname;
3368  char *xmlcn;
3369  char *catalogtypename;
3370  StringInfoData result;
3371  ListCell *cell;
3372 
3373  dbname = get_database_name(MyDatabaseId);
3374 
3375  initStringInfo(&result);
3376 
3377  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3378 
3379  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3380  dbname,
3381  NULL,
3382  NULL);
3383 
3384  appendStringInfo(&result,
3385  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3386  appendStringInfoString(&result,
3387  " <xsd:all>\n");
3388 
3389  foreach(cell, nspid_list)
3390  {
3391  Oid nspid = lfirst_oid(cell);
3392  char *nspname = get_namespace_name(nspid);
3393  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3394  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3395  dbname,
3396  nspname,
3397  NULL);
3398 
3399  appendStringInfo(&result,
3400  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3401  xmlsn, schematypename);
3402  }
3403 
3404  appendStringInfoString(&result,
3405  " </xsd:all>\n");
3406  appendStringInfoString(&result,
3407  "</xsd:complexType>\n\n");
3408 
3409  appendStringInfo(&result,
3410  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3411  xmlcn, catalogtypename);
3412 
3413  return result.data;
3414 }
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Oid MyDatabaseId
Definition: globals.c:85
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3155
char * dbname
Definition: streamutil.c:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

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

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert, buf, StringInfoData::data, 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().

2038 {
2039 #ifdef USE_LIBXML
2041  const char *p;
2042 
2043  /*
2044  * SQL/XML doesn't make use of this case anywhere, so it's probably a
2045  * mistake.
2046  */
2047  Assert(fully_escaped || !escape_period);
2048 
2049  initStringInfo(&buf);
2050 
2051  for (p = ident; *p; p += pg_mblen(p))
2052  {
2053  if (*p == ':' && (p == ident || fully_escaped))
2054  appendStringInfoString(&buf, "_x003A_");
2055  else if (*p == '_' && *(p + 1) == 'x')
2056  appendStringInfoString(&buf, "_x005F_");
2057  else if (fully_escaped && p == ident &&
2058  pg_strncasecmp(p, "xml", 3) == 0)
2059  {
2060  if (*p == 'x')
2061  appendStringInfoString(&buf, "_x0078_");
2062  else
2063  appendStringInfoString(&buf, "_x0058_");
2064  }
2065  else if (escape_period && *p == '.')
2066  appendStringInfoString(&buf, "_x002E_");
2067  else
2068  {
2069  pg_wchar u = sqlchar_to_unicode(p);
2070 
2071  if ((p == ident)
2072  ? !is_valid_xml_namefirst(u)
2073  : !is_valid_xml_namechar(u))
2074  appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
2075  else
2076  appendBinaryStringInfo(&buf, p, pg_mblen(p));
2077  }
2078  }
2079 
2080  return buf.data;
2081 #else /* not USE_LIBXML */
2082  NO_XML_SUPPORT();
2083  return NULL;
2084 #endif /* not USE_LIBXML */
2085 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define Assert(condition)
Definition: c.h:739
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

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

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

Referenced by schema_to_xmlschema_internal().

3293 {
3294  char *dbname;
3295  char *nspname;
3296  char *xmlsn;
3297  char *schematypename;
3298  StringInfoData result;
3299  ListCell *cell;
3300 
3301  dbname = get_database_name(MyDatabaseId);
3302  nspname = get_namespace_name(nspid);
3303 
3304  initStringInfo(&result);
3305 
3306  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3307 
3308  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3309  dbname,
3310  nspname,
3311  NULL);
3312 
3313  appendStringInfo(&result,
3314  "<xsd:complexType name=\"%s\">\n", schematypename);
3315  if (!tableforest)
3316  appendStringInfoString(&result,
3317  " <xsd:all>\n");
3318  else
3319  appendStringInfoString(&result,
3320  " <xsd:sequence>\n");
3321 
3322  foreach(cell, relid_list)
3323  {
3324  Oid relid = lfirst_oid(cell);
3325  char *relname = get_rel_name(relid);
3326  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3327  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3328  dbname,
3329  nspname,
3330  relname);
3331 
3332  if (!tableforest)
3333  appendStringInfo(&result,
3334  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3335  xmltn, tabletypename);
3336  else
3337  appendStringInfo(&result,
3338  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3339  xmltn, tabletypename);
3340  }
3341 
3342  if (!tableforest)
3343  appendStringInfoString(&result,
3344  " </xsd:all>\n");
3345  else
3346  appendStringInfoString(&result,
3347  " </xsd:sequence>\n");
3348  appendStringInfoString(&result,
3349  "</xsd:complexType>\n\n");
3350 
3351  appendStringInfo(&result,
3352  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3353  xmlsn, schematypename);
3354 
3355  return result.data;
3356 }
NameData relname
Definition: pg_class.h:35
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Oid MyDatabaseId
Definition: globals.c:85
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3155
char * dbname
Definition: streamutil.c:50
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define lfirst_oid(lc)
Definition: pg_list.h:192

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

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

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

3188 {
3189  int i;
3190  char *xmltn;
3191  char *tabletypename;
3192  char *rowtypename;
3193  StringInfoData result;
3194 
3195  initStringInfo(&result);
3196 
3197  if (OidIsValid(relid))
3198  {
3199  HeapTuple tuple;
3200  Form_pg_class reltuple;
3201 
3202  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3203  if (!HeapTupleIsValid(tuple))
3204  elog(ERROR, "cache lookup failed for relation %u", relid);
3205  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3206 
3207  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3208  true, false);
3209 
3210  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3212  get_namespace_name(reltuple->relnamespace),
3213  NameStr(reltuple->relname));
3214 
3215  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3217  get_namespace_name(reltuple->relnamespace),
3218  NameStr(reltuple->relname));
3219 
3220  ReleaseSysCache(tuple);
3221  }
3222  else
3223  {
3224  if (tableforest)
3225  xmltn = "row";
3226  else
3227  xmltn = "table";
3228 
3229  tabletypename = "TableType";
3230  rowtypename = "RowType";
3231  }
3232 
3233  xsd_schema_element_start(&result, targetns);
3234 
3235  appendStringInfoString(&result,
3237 
3238  appendStringInfo(&result,
3239  "<xsd:complexType name=\"%s\">\n"
3240  " <xsd:sequence>\n",
3241  rowtypename);
3242 
3243  for (i = 0; i < tupdesc->natts; i++)
3244  {
3245  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3246 
3247  if (att->attisdropped)
3248  continue;
3249  appendStringInfo(&result,
3250  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3252  true, false),
3253  map_sql_type_to_xml_name(att->atttypid, -1),
3254  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3255  }
3256 
3257  appendStringInfoString(&result,
3258  " </xsd:sequence>\n"
3259  "</xsd:complexType>\n\n");
3260 
3261  if (!tableforest)
3262  {
3263  appendStringInfo(&result,
3264  "<xsd:complexType name=\"%s\">\n"
3265  " <xsd:sequence>\n"
3266  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3267  " </xsd:sequence>\n"
3268  "</xsd:complexType>\n\n",
3269  tabletypename, rowtypename);
3270 
3271  appendStringInfo(&result,
3272  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3273  xmltn, tabletypename);
3274  }
3275  else
3276  appendStringInfo(&result,
3277  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3278  xmltn, rowtypename);
3279 
3280  xsd_schema_element_end(&result);
3281 
3282  return result.data;
3283 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2916
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define OidIsValid(objectId)
Definition: c.h:645
#define list_make1(x1)
Definition: pg_list.h:227
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3526
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3421
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2933
Oid MyDatabaseId
Definition: globals.c:85
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3155
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
#define elog(elevel,...)
Definition: elog.h:228
int i
#define NameStr(name)
Definition: c.h:616

◆ map_sql_type_to_xml_name()

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

Definition at line 3421 of file xml.c.

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

Referenced by map_sql_table_to_xmlschema(), and map_sql_type_to_xmlschema_type().

3422 {
3423  StringInfoData result;
3424 
3425  initStringInfo(&result);
3426 
3427  switch (typeoid)
3428  {
3429  case BPCHAROID:
3430  if (typmod == -1)
3431  appendStringInfoString(&result, "CHAR");
3432  else
3433  appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3434  break;
3435  case VARCHAROID:
3436  if (typmod == -1)
3437  appendStringInfoString(&result, "VARCHAR");
3438  else
3439  appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3440  break;
3441  case NUMERICOID:
3442  if (typmod == -1)
3443  appendStringInfoString(&result, "NUMERIC");
3444  else
3445  appendStringInfo(&result, "NUMERIC_%d_%d",
3446  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3447  (typmod - VARHDRSZ) & 0xffff);
3448  break;
3449  case INT4OID:
3450  appendStringInfoString(&result, "INTEGER");
3451  break;
3452  case INT2OID:
3453  appendStringInfoString(&result, "SMALLINT");
3454  break;
3455  case INT8OID:
3456  appendStringInfoString(&result, "BIGINT");
3457  break;
3458  case FLOAT4OID:
3459  appendStringInfoString(&result, "REAL");
3460  break;
3461  case FLOAT8OID:
3462  appendStringInfoString(&result, "DOUBLE");
3463  break;
3464  case BOOLOID:
3465  appendStringInfoString(&result, "BOOLEAN");
3466  break;
3467  case TIMEOID:
3468  if (typmod == -1)
3469  appendStringInfoString(&result, "TIME");
3470  else
3471  appendStringInfo(&result, "TIME_%d", typmod);
3472  break;
3473  case TIMETZOID:
3474  if (typmod == -1)
3475  appendStringInfoString(&result, "TIME_WTZ");
3476  else
3477  appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3478  break;
3479  case TIMESTAMPOID:
3480  if (typmod == -1)
3481  appendStringInfoString(&result, "TIMESTAMP");
3482  else
3483  appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3484  break;
3485  case TIMESTAMPTZOID:
3486  if (typmod == -1)
3487  appendStringInfoString(&result, "TIMESTAMP_WTZ");
3488  else
3489  appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3490  break;
3491  case DATEOID:
3492  appendStringInfoString(&result, "DATE");
3493  break;
3494  case XMLOID:
3495  appendStringInfoString(&result, "XML");
3496  break;
3497  default:
3498  {
3499  HeapTuple tuple;
3500  Form_pg_type typtuple;
3501 
3502  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3503  if (!HeapTupleIsValid(tuple))
3504  elog(ERROR, "cache lookup failed for type %u", typeoid);
3505  typtuple = (Form_pg_type) GETSTRUCT(tuple);
3506 
3507  appendStringInfoString(&result,
3508  map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3510  get_namespace_name(typtuple->typnamespace),
3511  NameStr(typtuple->typname)));
3512 
3513  ReleaseSysCache(tuple);
3514  }
3515  }
3516 
3517  return result.data;
3518 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define VARHDRSZ
Definition: c.h:562
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Oid MyDatabaseId
Definition: globals.c:85
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3155
FormData_pg_type * Form_pg_type
Definition: pg_type.h:250
#define elog(elevel,...)
Definition: elog.h:228
#define NameStr(name)
Definition: c.h:616

◆ map_sql_type_to_xmlschema_type()

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

Definition at line 3581 of file xml.c.

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

Referenced by map_sql_typecoll_to_xmlschema_types().

3582 {
3583  StringInfoData result;
3584  const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3585 
3586  initStringInfo(&result);
3587 
3588  if (typeoid == XMLOID)
3589  {
3590  appendStringInfoString(&result,
3591  "<xsd:complexType mixed=\"true\">\n"
3592  " <xsd:sequence>\n"
3593  " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3594  " </xsd:sequence>\n"
3595  "</xsd:complexType>\n");
3596  }
3597  else
3598  {
3599  appendStringInfo(&result,
3600  "<xsd:simpleType name=\"%s\">\n", typename);
3601 
3602  switch (typeoid)
3603  {
3604  case BPCHAROID:
3605  case VARCHAROID:
3606  case TEXTOID:
3607  appendStringInfoString(&result,
3608  " <xsd:restriction base=\"xsd:string\">\n");
3609  if (typmod != -1)
3610  appendStringInfo(&result,
3611  " <xsd:maxLength value=\"%d\"/>\n",
3612  typmod - VARHDRSZ);
3613  appendStringInfoString(&result, " </xsd:restriction>\n");
3614  break;
3615 
3616  case BYTEAOID:
3617  appendStringInfo(&result,
3618  " <xsd:restriction base=\"xsd:%s\">\n"
3619  " </xsd:restriction>\n",
3620  xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3621  break;
3622 
3623  case NUMERICOID:
3624  if (typmod != -1)
3625  appendStringInfo(&result,
3626  " <xsd:restriction base=\"xsd:decimal\">\n"
3627  " <xsd:totalDigits value=\"%d\"/>\n"
3628  " <xsd:fractionDigits value=\"%d\"/>\n"
3629  " </xsd:restriction>\n",
3630  ((typmod - VARHDRSZ) >> 16) & 0xffff,
3631  (typmod - VARHDRSZ) & 0xffff);
3632  break;
3633 
3634  case INT2OID:
3635  appendStringInfo(&result,
3636  " <xsd:restriction base=\"xsd:short\">\n"
3637  " <xsd:maxInclusive value=\"%d\"/>\n"
3638  " <xsd:minInclusive value=\"%d\"/>\n"
3639  " </xsd:restriction>\n",
3640  SHRT_MAX, SHRT_MIN);
3641  break;
3642 
3643  case INT4OID:
3644  appendStringInfo(&result,
3645  " <xsd:restriction base=\"xsd:int\">\n"
3646  " <xsd:maxInclusive value=\"%d\"/>\n"
3647  " <xsd:minInclusive value=\"%d\"/>\n"
3648  " </xsd:restriction>\n",
3649  INT_MAX, INT_MIN);
3650  break;
3651 
3652  case INT8OID:
3653  appendStringInfo(&result,
3654  " <xsd:restriction base=\"xsd:long\">\n"
3655  " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3656  " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3657  " </xsd:restriction>\n",
3658  (((uint64) 1) << (sizeof(int64) * 8 - 1)) - 1,
3659  (((uint64) 1) << (sizeof(int64) * 8 - 1)));
3660  break;
3661 
3662  case FLOAT4OID:
3663  appendStringInfoString(&result,
3664  " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3665  break;
3666 
3667  case FLOAT8OID:
3668  appendStringInfoString(&result,
3669  " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3670  break;
3671 
3672  case BOOLOID:
3673  appendStringInfoString(&result,
3674  " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
3675  break;
3676 
3677  case TIMEOID:
3678  case TIMETZOID:
3679  {
3680  const char *tz = (typeoid == TIMETZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3681 
3682  if (typmod == -1)
3683  appendStringInfo(&result,
3684  " <xsd:restriction base=\"xsd:time\">\n"
3685  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
3686  " </xsd:restriction>\n", tz);
3687  else if (typmod == 0)
3688  appendStringInfo(&result,
3689  " <xsd:restriction base=\"xsd:time\">\n"
3690  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3691  " </xsd:restriction>\n", tz);
3692  else
3693  appendStringInfo(&result,
3694  " <xsd:restriction base=\"xsd:time\">\n"
3695  " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
3696  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3697  break;
3698  }
3699 
3700  case TIMESTAMPOID:
3701  case TIMESTAMPTZOID:
3702  {
3703  const char *tz = (typeoid == TIMESTAMPTZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
3704 
3705  if (typmod == -1)
3706  appendStringInfo(&result,
3707  " <xsd:restriction base=\"xsd:dateTime\">\n"
3708  " <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"
3709  " </xsd:restriction>\n", tz);
3710  else if (typmod == 0)
3711  appendStringInfo(&result,
3712  " <xsd:restriction base=\"xsd:dateTime\">\n"
3713  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
3714  " </xsd:restriction>\n", tz);
3715  else
3716  appendStringInfo(&result,
3717  " <xsd:restriction base=\"xsd:dateTime\">\n"
3718  " <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"
3719  " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
3720  break;
3721  }
3722 
3723  case DATEOID:
3724  appendStringInfoString(&result,
3725  " <xsd:restriction base=\"xsd:date\">\n"
3726  " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
3727  " </xsd:restriction>\n");
3728  break;
3729 
3730  default:
3731  if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
3732  {
3733  Oid base_typeoid;
3734  int32 base_typmod = -1;
3735 
3736  base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
3737 
3738  appendStringInfo(&result,
3739  " <xsd:restriction base=\"%s\"/>\n",
3740  map_sql_type_to_xml_name(base_typeoid, base_typmod));
3741  }
3742  break;
3743  }
3744  appendStringInfoString(&result, "</xsd:simpleType>\n");
3745  }
3746 
3747  return result.data;
3748 }
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2316
#define VARHDRSZ
Definition: c.h:562
char get_typtype(Oid typid)
Definition: lsyscache.c:2407
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:347
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3421
int xmlbinary
Definition: xml.c:97
#define INT64_FORMAT
Definition: c.h:401

◆ map_sql_typecoll_to_xmlschema_types()

static const char * map_sql_typecoll_to_xmlschema_types ( List tupdesc_list)
static

Definition at line 3526 of file xml.c.

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

3527 {
3528  List *uniquetypes = NIL;
3529  int i;
3530  StringInfoData result;
3531  ListCell *cell0;
3532 
3533  /* extract all column types used in the set of TupleDescs */
3534  foreach(cell0, tupdesc_list)
3535  {
3536  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3537 
3538  for (i = 0; i < tupdesc->natts; i++)
3539  {
3540  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3541 
3542  if (att->attisdropped)
3543  continue;
3544  uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3545  }
3546  }
3547 
3548  /* add base types of domains */
3549  foreach(cell0, uniquetypes)
3550  {
3551  Oid typid = lfirst_oid(cell0);
3552  Oid basetypid = getBaseType(typid);
3553 
3554  if (basetypid != typid)
3555  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3556  }
3557 
3558  /* Convert to textual form */
3559  initStringInfo(&result);
3560 
3561  foreach(cell0, uniquetypes)
3562  {
3563  appendStringInfo(&result, "%s\n",
3565  -1));
3566  }
3567 
3568  return result.data;
3569 }
#define NIL
Definition: pg_list.h:65
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1218
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:190
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89
int i
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2299
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3581
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ map_sql_value_to_xml_value()

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

Definition at line 2152 of file xml.c.

References appendStringInfoString(), ARR_ELEMTYPE, buf, StringInfoData::data, 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(), map_sql_value_to_xml_value(), 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, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, type_is_array_domain, USE_XSD_DATES, VARDATA_ANY, VARSIZE_ANY_EXHDR, xml_ereport(), xmlbinary, and XMLBINARY_BASE64.

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

2153 {
2155  {
2156  ArrayType *array;
2157  Oid elmtype;
2158  int16 elmlen;
2159  bool elmbyval;
2160  char elmalign;
2161  int num_elems;
2162  Datum *elem_values;
2163  bool *elem_nulls;
2165  int i;
2166 
2167  array = DatumGetArrayTypeP(value);
2168  elmtype = ARR_ELEMTYPE(array);
2169  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2170 
2171  deconstruct_array(array, elmtype,
2172  elmlen, elmbyval, elmalign,
2173  &elem_values, &elem_nulls,
2174  &num_elems);
2175 
2176  initStringInfo(&buf);
2177 
2178  for (i = 0; i < num_elems; i++)
2179  {
2180  if (elem_nulls[i])
2181  continue;
2182  appendStringInfoString(&buf, "<element>");
2184  map_sql_value_to_xml_value(elem_values[i],
2185  elmtype, true));
2186  appendStringInfoString(&buf, "</element>");
2187  }
2188 
2189  pfree(elem_values);
2190  pfree(elem_nulls);
2191 
2192  return buf.data;
2193  }
2194  else
2195  {
2196  Oid typeOut;
2197  bool isvarlena;
2198  char *str;
2199 
2200  /*
2201  * Flatten domains; the special-case treatments below should apply to,
2202  * eg, domains over boolean not just boolean.
2203  */
2204  type = getBaseType(type);
2205 
2206  /*
2207  * Special XSD formatting for some data types
2208  */
2209  switch (type)
2210  {
2211  case BOOLOID:
2212  if (DatumGetBool(value))
2213  return "true";
2214  else
2215  return "false";
2216 
2217  case DATEOID:
2218  {
2219  DateADT date;
2220  struct pg_tm tm;
2221  char buf[MAXDATELEN + 1];
2222 
2223  date = DatumGetDateADT(value);
2224  /* XSD doesn't support infinite values */
2225  if (DATE_NOT_FINITE(date))
2226  ereport(ERROR,
2227  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2228  errmsg("date out of range"),
2229  errdetail("XML does not support infinite date values.")));
2231  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2233 
2234  return pstrdup(buf);
2235  }
2236 
2237  case TIMESTAMPOID:
2238  {
2240  struct pg_tm tm;
2241  fsec_t fsec;
2242  char buf[MAXDATELEN + 1];
2243 
2244  timestamp = DatumGetTimestamp(value);
2245 
2246  /* XSD doesn't support infinite values */
2247  if (TIMESTAMP_NOT_FINITE(timestamp))
2248  ereport(ERROR,
2249  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2250  errmsg("timestamp out of range"),
2251  errdetail("XML does not support infinite timestamp values.")));
2252  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2253  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2254  else
2255  ereport(ERROR,
2256  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2257  errmsg("timestamp out of range")));
2258 
2259  return pstrdup(buf);
2260  }
2261 
2262  case TIMESTAMPTZOID:
2263  {
2265  struct pg_tm tm;
2266  int tz;
2267  fsec_t fsec;
2268  const char *tzn = NULL;
2269  char buf[MAXDATELEN + 1];
2270 
2271  timestamp = DatumGetTimestamp(value);
2272 
2273  /* XSD doesn't support infinite values */
2274  if (TIMESTAMP_NOT_FINITE(timestamp))
2275  ereport(ERROR,
2276  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2277  errmsg("timestamp out of range"),
2278  errdetail("XML does not support infinite timestamp values.")));
2279  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2280  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2281  else
2282  ereport(ERROR,
2283  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2284  errmsg("timestamp out of range")));
2285 
2286  return pstrdup(buf);
2287  }
2288 
2289 #ifdef USE_LIBXML
2290  case BYTEAOID:
2291  {
2292  bytea *bstr = DatumGetByteaPP(value);
2293  PgXmlErrorContext *xmlerrcxt;
2294  volatile xmlBufferPtr buf = NULL;
2295  volatile xmlTextWriterPtr writer = NULL;
2296  char *result;
2297 
2298  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2299 
2300  PG_TRY();
2301  {
2302  buf = xmlBufferCreate();
2303  if (buf == NULL || xmlerrcxt->err_occurred)
2304  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2305  "could not allocate xmlBuffer");
2306  writer = xmlNewTextWriterMemory(buf, 0);
2307  if (writer == NULL || xmlerrcxt->err_occurred)
2308  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2309  "could not allocate xmlTextWriter");
2310 
2311  if (xmlbinary == XMLBINARY_BASE64)
2312  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2313  0, VARSIZE_ANY_EXHDR(bstr));
2314  else
2315  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2316  0, VARSIZE_ANY_EXHDR(bstr));
2317 
2318  /* we MUST do this now to flush data out to the buffer */
2319  xmlFreeTextWriter(writer);
2320  writer = NULL;
2321 
2322  result = pstrdup((const char *) xmlBufferContent(buf));
2323  }
2324  PG_CATCH();
2325  {
2326  if (writer)
2327  xmlFreeTextWriter(writer);
2328  if (buf)
2329  xmlBufferFree(buf);
2330 
2331  pg_xml_done(xmlerrcxt, true);
2332 
2333  PG_RE_THROW();
2334  }
2335  PG_END_TRY();
2336 
2337  xmlBufferFree(buf);
2338 
2339  pg_xml_done(xmlerrcxt, false);
2340 
2341  return result;
2342  }
2343 #endif /* USE_LIBXML */
2344 
2345  }
2346 
2347  /*
2348  * otherwise, just use the type's native text representation
2349  */
2350  getTypeOutputInfo(type, &typeOut, &isvarlena);
2351  str = OidOutputFunctionCall(typeOut, value);
2352 
2353  /* ... exactly as-is for XML, and when escaping is not wanted */
2354  if (type == XMLOID || !xml_escape_strings)
2355  return str;
2356 
2357  /* otherwise, translate special characters as needed */
2358  return escape_xml(str);
2359  }
2360 }
#define MAXDATELEN
Definition: datetime.h:201
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3855
signed short int16
Definition: c.h:346
#define DatumGetDateADT(X)
Definition: date.h:53
#define type_is_array_domain(typid)
Definition: lsyscache.h:186
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int32 DateADT
Definition: date.h:23
int64 timestamp
int64 TimestampTz
Definition: timestamp.h:39
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2049
char * pstrdup(const char *in)
Definition: mcxt.c:1186
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1791
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:608
#define DatumGetByteaPP(X)
Definition: fmgr.h:285
long date
Definition: pgtypes_date.h:9
Definition: pgtime.h:25
unsigned int Oid
Definition: postgres_ext.h:31
static struct pg_tm tm
Definition: localtime.c:108
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define DATE_NOT_FINITE(j)
Definition: date.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:67
int tm_mon
Definition: pgtime.h:31
int errdetail(const char *fmt,...)
Definition: elog.c:955
#define DatumGetBool(X)
Definition: postgres.h:393
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3970
int32 fsec_t
Definition: timestamp.h:41
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
#define ereport(elevel, rest)
Definition: elog.h:141
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:294
int64 Timestamp
Definition: timestamp.h:38
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:367
#define PG_CATCH()
Definition: elog.h:332
#define PG_RE_THROW()
Definition: elog.h:363
int xmlbinary
Definition: xml.c:97
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
#define USE_XSD_DATES
Definition: miscadmin.h:217
int tm_year
Definition: pgtime.h:32
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1655
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
Definition: c.h:556
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
char * escape_xml(const char *str)
Definition: xml.c:2371
#define PG_TRY()
Definition: elog.h:322
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2152
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2299
#define ARR_ELEMTYPE(a)
Definition: array.h:280
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:347
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
#define DatumGetTimestamp(X)
Definition: timestamp.h:27
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ map_xml_name_to_sql_identifier()

char* map_xml_name_to_sql_identifier ( const char *  name)

Definition at line 2112 of file xml.c.

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

Referenced by get_rule_expr().

2113 {
2115  const char *p;
2116 
2117  initStringInfo(&buf);
2118 
2119  for (p = name; *p; p += pg_mblen(p))
2120  {
2121  if (*p == '_' && *(p + 1) == 'x'
2122  && isxdigit((unsigned char) *(p + 2))
2123  && isxdigit((unsigned char) *(p + 3))
2124  && isxdigit((unsigned char) *(p + 4))
2125  && isxdigit((unsigned char) *(p + 5))
2126  && *(p + 6) == '_')
2127  {
2128  unsigned int u;
2129 
2130  sscanf(p + 2, "%X", &u);
2132  p += 6;
2133  }
2134  else
2135  appendBinaryStringInfo(&buf, p, pg_mblen(p));
2136  }
2137 
2138  return buf.data;
2139 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
const char * name
Definition: encode.c:521
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
static char * unicode_to_sqlchar(pg_wchar c)
Definition: xml.c:2092

◆ query_to_oid_list()

static List* query_to_oid_list ( const char *  query)
static

Definition at line 2460 of file xml.c.

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

2461 {
2462  uint64 i;
2463  List *list = NIL;
2464  int spi_result;
2465 
2466  spi_result = SPI_execute(query, true, 0);
2467  if (spi_result != SPI_OK_SELECT)
2468  elog(ERROR, "SPI_execute returned %s for %s",
2469  SPI_result_code_string(spi_result), query);
2470 
2471  for (i = 0; i < SPI_processed; i++)
2472  {
2473  Datum oid;
2474  bool isnull;
2475 
2476  oid = SPI_getbinval(SPI_tuptable->vals[i],
2478  1,
2479  &isnull);
2480  if (!isnull)
2481  list = lappend_oid(list, DatumGetObjectId(oid));
2482  }
2483 
2484  return list;
2485 }
#define NIL
Definition: pg_list.h:65
#define DatumGetObjectId(X)
Definition: postgres.h:500
SPITupleTable * SPI_tuptable
Definition: spi.c:46
HeapTuple * vals
Definition: spi.h:26
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
uint64 SPI_processed
Definition: spi.c:45
#define ERROR
Definition: elog.h:43
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1028
const char * SPI_result_code_string(int code)
Definition: spi.c:1705
uintptr_t Datum
Definition: postgres.h:367
TupleDesc tupdesc
Definition: spi.h:25
#define SPI_OK_SELECT
Definition: spi.h:57
#define elog(elevel,...)
Definition: elog.h:228
int i
Definition: pg_list.h:50
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:496

◆ query_to_xml()

Datum query_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2573 of file xml.c.

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

2574 {
2575  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2576  bool nulls = PG_GETARG_BOOL(1);
2577  bool tableforest = PG_GETARG_BOOL(2);
2578  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2579 
2581  NULL, nulls, tableforest,
2582  targetns, true)));
2583 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2675
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447

◆ query_to_xml_and_xmlschema()

Datum query_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2815 of file xml.c.

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

2816 {
2817  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2818  bool nulls = PG_GETARG_BOOL(1);
2819  bool tableforest = PG_GETARG_BOOL(2);
2820  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2821 
2822  const char *xmlschema;
2823  SPIPlanPtr plan;
2824  Portal portal;
2825 
2826  SPI_connect();
2827 
2828  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2829  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2830 
2831  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2832  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2833 
2834  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2835  InvalidOid, nulls, tableforest, targetns));
2836  SPI_cursor_close(portal);
2837  SPI_finish();
2838 
2840  xmlschema, nulls, tableforest,
2841  targetns, true)));
2842 }
int SPI_connect(void)
Definition: spi.c:89
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:674
int SPI_finish(void)
Definition: spi.c:176
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1221
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2403
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3186
TupleDesc tupDesc
Definition: portal.h:157
#define InvalidOid
Definition: postgres_ext.h:36
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2675
void SPI_cursor_close(Portal portal)
Definition: spi.c:1595
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
#define elog(elevel,...)
Definition: elog.h:228

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

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

2678 {
2679  StringInfo result;
2680  char *xmltn;
2681  uint64 i;
2682 
2683  if (tablename)
2684  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2685  else
2686  xmltn = "table";
2687 
2688  result = makeStringInfo();
2689 
2690  SPI_connect();
2691  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2692  ereport(ERROR,
2693  (errcode(ERRCODE_DATA_EXCEPTION),
2694  errmsg("invalid query")));
2695 
2696  if (!tableforest)
2697  {
2698  xmldata_root_element_start(result, xmltn, xmlschema,
2699  targetns, top_level);
2700  appendStringInfoChar(result, '\n');
2701  }
2702 
2703  if (xmlschema)
2704  appendStringInfo(result, "%s\n\n", xmlschema);
2705 
2706  for (i = 0; i < SPI_processed; i++)
2707  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2708  tableforest, targetns, top_level);
2709 
2710  if (!tableforest)
2711  xmldata_root_element_end(result, xmltn);
2712 
2713  SPI_finish();
2714 
2715  return result;
2716 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2641
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
int errcode(int sqlerrcode)
Definition: elog.c:608
uint64 SPI_processed
Definition: spi.c:45
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ERROR
Definition: elog.h:43
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#define SPI_OK_SELECT
Definition: spi.h:57
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2668
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
static void SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3756
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:496

◆ query_to_xmlschema()

Datum query_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2739 of file xml.c.

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, SPI_connect(), SPI_cursor_close(), SPI_cursor_open(), SPI_finish(), SPI_prepare(), text_to_cstring(), and PortalData::tupDesc.

2740 {
2741  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2742  bool nulls = PG_GETARG_BOOL(1);
2743  bool tableforest = PG_GETARG_BOOL(2);
2744  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2745  const char *result;
2746  SPIPlanPtr plan;
2747  Portal portal;
2748 
2749  SPI_connect();
2750 
2751  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2752  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2753 
2754  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2755  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2756 
2758  InvalidOid, nulls,
2759  tableforest, targetns));
2760  SPI_cursor_close(portal);
2761  SPI_finish();
2762 
2764 }
int SPI_connect(void)
Definition: spi.c:89
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:674
int SPI_finish(void)
Definition: spi.c:176
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1221
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
static char * _SPI_strdup(const char *s)
Definition: xml.c:2403
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3186
TupleDesc tupDesc
Definition: portal.h:157
#define InvalidOid
Definition: postgres_ext.h:36
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:454
void SPI_cursor_close(Portal portal)
Definition: spi.c:1595
char * text_to_cstring(const text *t)
Definition: varlena.c:204
#define elog(elevel,...)
Definition: elog.h:228

◆ schema_get_xml_visible_tables()

static List* schema_get_xml_visible_tables ( Oid  nspid)
static

Definition at line 2489 of file xml.c.

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

Referenced by schema_to_xml_internal(), and schema_to_xmlschema_internal().

2490 {
2491  StringInfoData query;
2492 
2493  initStringInfo(&query);
2494  appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2495  " WHERE relnamespace = %u AND relkind IN ("
2496  CppAsString2(RELKIND_RELATION) ","
2497  CppAsString2(RELKIND_MATVIEW) ","
2498  CppAsString2(RELKIND_VIEW) ")"
2499  " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2500  " ORDER BY relname;", nspid);
2501 
2502  return query_to_oid_list(query.data);
2503 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2460
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define CppAsString2(x)
Definition: c.h:224

◆ schema_to_xml()

Datum schema_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2894 of file xml.c.

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

2895 {
2896  Name name = PG_GETARG_NAME(0);
2897  bool nulls = PG_GETARG_BOOL(1);
2898  bool tableforest = PG_GETARG_BOOL(2);
2899  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2900 
2901  char *schemaname;
2902  Oid nspid;
2903 
2904  schemaname = NameStr(*name);
2905  nspid = LookupExplicitNamespace(schemaname, false);
2906 
2908  nulls, tableforest, targetns, true)));
2909 }
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2851
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Definition: c.h:610
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
#define NameStr(name)
Definition: c.h:616
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ schema_to_xml_and_xmlschema()

Datum schema_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2998 of file xml.c.

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

2999 {
3000  Name name = PG_GETARG_NAME(0);
3001  bool nulls = PG_GETARG_BOOL(1);
3002  bool tableforest = PG_GETARG_BOOL(2);
3003  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3004  char *schemaname;
3005  Oid nspid;
3006  StringInfo xmlschema;
3007 
3008  schemaname = NameStr(*name);
3009  nspid = LookupExplicitNamespace(schemaname, false);
3010 
3011  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3012  tableforest, targetns);
3013 
3015  xmlschema->data, nulls,
3016  tableforest, targetns, true)));
3017 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2940
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2851
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Definition: c.h:610
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
#define NameStr(name)
Definition: c.h:616
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

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

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

2853 {
2854  StringInfo result;
2855  char *xmlsn;
2856  List *relid_list;
2857  ListCell *cell;
2858 
2860  true, false);
2861  result = makeStringInfo();
2862 
2863  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
2864  appendStringInfoChar(result, '\n');
2865 
2866  if (xmlschema)
2867  appendStringInfo(result, "%s\n\n", xmlschema);
2868 
2869  SPI_connect();
2870 
2871  relid_list = schema_get_xml_visible_tables(nspid);
2872 
2873  foreach(cell, relid_list)
2874  {
2875  Oid relid = lfirst_oid(cell);
2876  StringInfo subres;
2877 
2878  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
2879  targetns, false);
2880 
2881  appendBinaryStringInfo(result, subres->data, subres->len);
2882  appendStringInfoChar(result, '\n');
2883  }
2884 
2885  SPI_finish();
2886 
2887  xmldata_root_element_end(result, xmlsn);
2888 
2889  return result;
2890 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2641
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2489
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2542
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2668
Definition: pg_list.h:50
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ schema_to_xmlschema()

Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2985 of file xml.c.

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

2986 {
2987  Name name = PG_GETARG_NAME(0);
2988  bool nulls = PG_GETARG_BOOL(1);
2989  bool tableforest = PG_GETARG_BOOL(2);
2990  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2991 
2993  nulls, tableforest, targetns)));
2994 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2940
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Definition: c.h:610
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
#define NameStr(name)
Definition: c.h:616
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ schema_to_xmlschema_internal()

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

Definition at line 2940 of file xml.c.

References AccessShareLock, appendStringInfoString(), CreateTupleDescCopy(), lappend(), lfirst_oid, LookupExplicitNamespace(), makeStringInfo(), map_sql_schema_to_xmlschema_types(), map_sql_typecoll_to_xmlschema_types(), NIL, NoLock, 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().

2942 {
2943  Oid nspid;
2944  List *relid_list;
2945  List *tupdesc_list;
2946  ListCell *cell;
2947  StringInfo result;
2948 
2949  result = makeStringInfo();
2950 
2951  nspid = LookupExplicitNamespace(schemaname, false);
2952 
2953  xsd_schema_element_start(result, targetns);
2954 
2955  SPI_connect();
2956 
2957  relid_list = schema_get_xml_visible_tables(nspid);
2958 
2959  tupdesc_list = NIL;
2960  foreach(cell, relid_list)
2961  {
2962  Relation rel;
2963 
2964  rel = table_open(lfirst_oid(cell), AccessShareLock);
2965  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2966  table_close(rel, NoLock);
2967  }
2968 
2969  appendStringInfoString(result,
2970  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2971 
2972  appendStringInfoString(result,
2973  map_sql_schema_to_xmlschema_types(nspid, relid_list,
2974  nulls, tableforest, targetns));
2975 
2976  xsd_schema_element_end(result);
2977 
2978  SPI_finish();
2979 
2980  return result;
2981 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2916
#define NIL
Definition: pg_list.h:65
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2489
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:322
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3526
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2933
TupleDesc rd_att
Definition: rel.h:84
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3291
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

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

References accumArrayResult(), appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, Assert, BoolGetDatum, generate_unaccent_rules::bytes(), cstring_to_text(), cstring_to_xmltype(), CStringGetDatum, cur, CurrentMemoryContext, deconstruct_array(), elog, ereport, errcode(), errdetail(), errmsg(), ERROR, escape_xml(), Float8GetDatum(), GetDatabaseEncoding(), i, map_sql_identifier_to_xml_name(), map_sql_value_to_xml_value(), TupleDescData::natts, pfree(), PG_CATCH, PG_END_TRY, PG_FINALLY, PG_RE_THROW, PG_TRY, PG_UTF8, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, PointerGetDatum, SPI_fname(), SPI_getbinval(), SPI_gettypeid(), SPI_tuptable, generate_unaccent_rules::str, TextDatumGetCString, SPITupleTable::tupdesc, SPITupleTable::vals, VARDATA, VARDATA_ANY, VARHDRSZ, VARSIZE, VARSIZE_ANY_EXHDR, xml_ereport(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by cursor_to_xml(), and query_to_xml_internal().

3759 {
3760  int i;
3761  char *xmltn;
3762 
3763  if (tablename)
3764  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3765  else
3766  {
3767  if (tableforest)
3768  xmltn = "row";
3769  else
3770  xmltn = "table";
3771  }
3772 
3773  if (tableforest)
3774  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
3775  else
3776  appendStringInfoString(result, "<row>\n");
3777 
3778  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
3779  {
3780  char *colname;
3781  Datum colval;
3782  bool isnull;
3783 
3785  true, false);
3786  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
3788  i,
3789  &isnull);
3790  if (isnull)
3791  {
3792  if (nulls)
3793  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
3794  }
3795  else
3796  appendStringInfo(result, " <%s>%s</%s>\n",
3797  colname,
3799  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
3800  colname);
3801  }
3802 
3803  if (tableforest)
3804  {
3805  xmldata_root_element_end(result, xmltn);
3806  appendStringInfoChar(result, '\n');
3807  }
3808  else
3809  appendStringInfoString(result, "</row>\n\n");
3810 }
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1084
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2641
SPITupleTable * SPI_tuptable
Definition: spi.c:46
HeapTuple * vals
Definition: spi.h:26
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:974
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1028
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2036
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
uintptr_t Datum
Definition: postgres.h:367
TupleDesc tupdesc
Definition: spi.h:25
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2668
int i
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2152

◆ stringinfo_to_xmltype()

◆ table_to_xml()

Datum table_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2559 of file xml.c.

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

2560 {
2561  Oid relid = PG_GETARG_OID(0);
2562  bool nulls = PG_GETARG_BOOL(1);
2563  bool tableforest = PG_GETARG_BOOL(2);
2564  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2565 
2567  nulls, tableforest,
2568  targetns, true)));
2569 }
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2542
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447

◆ table_to_xml_and_xmlschema()

Datum table_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2794 of file xml.c.

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

2795 {
2796  Oid relid = PG_GETARG_OID(0);
2797  bool nulls = PG_GETARG_BOOL(1);
2798  bool tableforest = PG_GETARG_BOOL(2);
2799  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2800  Relation rel;
2801  const char *xmlschema;
2802 
2803  rel = table_open(relid, AccessShareLock);
2804  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2805  tableforest, targetns);
2806  table_close(rel, NoLock);
2807 
2809  xmlschema, nulls, tableforest,
2810  targetns, true)));
2811 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define AccessShareLock
Definition: lockdefs.h:36
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define NoLock
Definition: lockdefs.h:34
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3186
TupleDesc rd_att
Definition: rel.h:84
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2542
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

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

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

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

2545 {
2546  StringInfoData query;
2547 
2548  initStringInfo(&query);
2549  appendStringInfo(&query, "SELECT * FROM %s",
2551  ObjectIdGetDatum(relid))));
2552  return query_to_xml_internal(query.data, get_rel_name(relid),
2553  xmlschema, nulls, tableforest,
2554  targetns, top_level);
2555 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:615
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define DatumGetCString(X)
Definition: postgres.h:566
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
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:2675
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:972
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730

◆ table_to_xmlschema()

Datum table_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 2720 of file xml.c.

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

2721 {
2722  Oid relid = PG_GETARG_OID(0);
2723  bool nulls = PG_GETARG_BOOL(1);
2724  bool tableforest = PG_GETARG_BOOL(2);
2725  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2726  const char *result;
2727  Relation rel;
2728 
2729  rel = table_open(relid, AccessShareLock);
2730  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2731  tableforest, targetns);
2732  table_close(rel, NoLock);
2733 
2735 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define AccessShareLock
Definition: lockdefs.h:36
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define NoLock
Definition: lockdefs.h:34
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3186
TupleDesc rd_att
Definition: rel.h:84
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:454
char * text_to_cstring(const text *t)
Definition: varlena.c:204
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ texttoxml()

Datum texttoxml ( PG_FUNCTION_ARGS  )

Definition at line 596 of file xml.c.

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

597 {
598  text *data = PG_GETARG_TEXT_PP(0);
599 
600  PG_RETURN_XML_P(xmlparse(data, xmloption, true));
601 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
int xmloption
Definition: xml.c:98
Definition: c.h:556
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:752

◆ unicode_to_sqlchar()

static char* unicode_to_sqlchar ( pg_wchar  c)
static

Definition at line 2092 of file xml.c.

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

Referenced by map_xml_name_to_sql_identifier().

2093 {
2094  char utf8string[8]; /* need room for trailing zero */
2095  char *result;
2096 
2097  memset(utf8string, 0, sizeof(utf8string));
2098  unicode_to_utf8(c, (unsigned char *) utf8string);
2099 
2100  result = pg_any_to_server(utf8string, strlen(utf8string), PG_UTF8);
2101  /* if pg_any_to_server didn't strdup, we must */
2102  if (result == utf8string)
2103  result = pstrdup(result);
2104  return result;
2105 }
unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
Definition: wchar.c:482
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * c
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:581

◆ xml_in()

Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 258 of file xml.c.

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

259 {
260 #ifdef USE_LIBXML
261  char *s = PG_GETARG_CSTRING(0);
262  xmltype *vardata;
263  xmlDocPtr doc;
264 
265  vardata = (xmltype *) cstring_to_text(s);
266 
267  /*
268  * Parse the data to check if it is well-formed XML data. Assume that
269  * ERROR occurred if parsing failed.
270  */
271  doc = xml_parse(vardata, xmloption, true, GetDatabaseEncoding());
272  xmlFreeDoc(doc);
273 
274  PG_RETURN_XML_P(vardata);
275 #else
276  NO_XML_SUPPORT();
277  return 0;
278 #endif
279 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
int GetDatabaseEncoding(void)
Definition: mbutils.c:1046
text * cstring_to_text(const char *s)
Definition: varlena.c:171
int xmloption
Definition: xml.c:98
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
Definition: c.h:556

◆ xml_is_document()

bool xml_is_document ( xmltype arg)

Definition at line 888 of file xml.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), Assert, CopyErrorData(), CurrentMemoryContext, StringInfoData::data, elog, encoding, ereport, errcode(), errdetail(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), ERROR, error(), FATAL, FlushErrorState(), GetDatabaseEncoding(), gettext_noop, initStringInfo(), StringInfoData::len, makeStringInfo(), MAX_MULTIBYTE_CHAR_LEN, MemoryContextAlloc(), MemoryContextStrdup(), MemoryContextSwitchTo(), name, NO_XML_SUPPORT, NOTICE, palloc(), pfree(), PG_CATCH, pg_do_encoding_conversion(), pg_encoding_mb2wchar_with_len(), pg_encoding_mblen(), pg_encoding_to_char(), PG_END_TRY, PG_FINALLY, pg_mblen(), PG_RE_THROW, pg_server_to_any(), PG_TRY, PG_UTF8, PG_XML_DEFAULT_VERSION, pg_xml_done(), pg_xml_error_occurred(), pg_xml_init(), pg_xml_init_library(), PG_XML_STRICTNESS_LEGACY, PG_XML_STRICTNESS_WELLFORMED, pstrdup(), repalloc(), ErrorData::sqlerrcode, generate_unaccent_rules::str, strnlen(), text_to_cstring(), TopMemoryContext, VARSIZE_ANY_EXHDR, WARNING, xml_ereport(), and XMLOPTION_DOCUMENT.

Referenced by ExecEvalXmlExpr(), and xmltotext_with_xmloption().

889 {
890 #ifdef USE_LIBXML
891  bool result;
892  volatile xmlDocPtr doc = NULL;
894 
895  /* We want to catch ereport(INVALID_XML_DOCUMENT) and return false */
896  PG_TRY();
897  {
898  doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
900  result = true;
901  }
902  PG_CATCH();
903  {
904  ErrorData *errdata;
905  MemoryContext ecxt;
906 
907  ecxt = MemoryContextSwitchTo(ccxt);
908  errdata = CopyErrorData();
909  if (errdata->sqlerrcode == ERRCODE_INVALID_XML_DOCUMENT)
910  {
911  FlushErrorState();
912  result = false;
913  }
914  else
915  {
916  MemoryContextSwitchTo(ecxt);
917  PG_RE_THROW();
918  }
919  }
920  PG_END_TRY();
921 
922  if (doc)
923  xmlFreeDoc(doc);
924 
925  return result;
926 #else /* not USE_LIBXML */
927  NO_XML_SUPPORT();
928  return false;
929 #endif /* not USE_LIBXML */
930 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int sqlerrcode
Definition: elog.h:391
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1678
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int GetDatabaseEncoding(void)
Definition: mbutils.c:1046
#define PG_CATCH()
Definition: elog.h:332
#define PG_RE_THROW()
Definition: elog.h:363
Definition: c.h:556
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347

◆ xml_is_well_formed()

Datum xml_is_well_formed ( PG_FUNCTION_ARGS  )

Definition at line 4281 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and xmloption.

4282 {
4283 #ifdef USE_LIBXML
4284  text *data = PG_GETARG_TEXT_PP(0);
4285 
4286  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4287 #else
4288  NO_XML_SUPPORT();
4289  return 0;
4290 #endif /* not USE_LIBXML */
4291 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
int xmloption
Definition: xml.c:98
Definition: c.h:556

◆ xml_is_well_formed_content()

Datum xml_is_well_formed_content ( PG_FUNCTION_ARGS  )

Definition at line 4307 of file xml.c.

References elog, ERROR, IsA, NO_XML_SUPPORT, TableFuncScanState::opaque, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_CONTENT.

4308 {
4309 #ifdef USE_LIBXML
4310  text *data = PG_GETARG_TEXT_PP(0);
4311 
4312  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4313 #else
4314  NO_XML_SUPPORT();
4315  return 0;
4316 #endif /* not USE_LIBXML */
4317 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: c.h:556

◆ xml_is_well_formed_document()

Datum xml_is_well_formed_document ( PG_FUNCTION_ARGS  )

Definition at line 4294 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.

4295 {
4296 #ifdef USE_LIBXML
4297  text *data = PG_GETARG_TEXT_PP(0);
4298 
4299  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4300 #else
4301  NO_XML_SUPPORT();
4302  return 0;
4303 #endif /* not USE_LIBXML */
4304 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: c.h:556

◆ xml_out()

Datum xml_out ( PG_FUNCTION_ARGS  )

Definition at line 336 of file xml.c.

References PG_GETARG_XML_P, PG_RETURN_CSTRING, and xml_out_internal().

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

◆ xml_out_internal()

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

Definition at line 293 of file xml.c.

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

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

294 {
295  char *str = text_to_cstring((text *) x);
296 
297 #ifdef USE_LIBXML
298  size_t len = strlen(str);
299  xmlChar *version;
300  int standalone;
301  int res_code;
302 
303  if ((res_code = parse_xml_decl((xmlChar *) str,
304  &len, &version, NULL, &standalone)) == 0)
305  {
307 
308  initStringInfo(&buf);
309 
310  if (!print_xml_decl(&buf, version, target_encoding, standalone))
311  {
312  /*
313  * If we are not going to produce an XML declaration, eat a single
314  * newline in the original string to prevent empty first lines in
315  * the output.
316  */
317  if (*(str + len) == '\n')
318  len += 1;
319  }
320  appendStringInfoString(&buf, str + len);
321 
322  pfree(str);
323 
324  return buf.data;
325  }
326 
327  xml_ereport_by_code(WARNING, ERRCODE_INTERNAL_ERROR,
328  "could not parse XML declaration in stored value",
329  res_code);
330 #endif
331  return str;
332 }
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define WARNING
Definition: elog.h:40
char * text_to_cstring(const text *t)
Definition: varlena.c:204
Definition: c.h:556

◆ xml_recv()

Datum xml_recv ( PG_FUNCTION_ARGS  )

Definition at line 351 of file xml.c.

References cstring_to_text(), StringInfoData::cursor, encoding, StringInfoData::len, 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.

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

◆ xml_send()

Datum xml_send ( PG_FUNCTION_ARGS  )

Definition at line 418 of file xml.c.

References appendBinaryStringInfo(), appendStringInfoText(), buf, pfree(), pg_get_client_encoding(), PG_GETARG_XML_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), VARDATA_ANY, VARSIZE_ANY_EXHDR, and xml_out_internal().

419 {
420  xmltype *x = PG_GETARG_XML_P(0);
421  char *outval;
423 
424  /*
425  * xml_out_internal doesn't convert the encoding, it just prints the right
426  * declaration. pq_sendtext will do the conversion.
427  */
429 
430  pq_begintypsend(&buf);
431  pq_sendtext(&buf, outval, strlen(outval));
432  pfree(outval);
434 }
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
void pfree(void *pointer)
Definition: mcxt.c:1056
static char * buf
Definition: pg_test_fsync.c:67
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
int pg_get_client_encoding(void)
Definition: mbutils.c:298
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:293
Definition: c.h:556

◆ xmlcomment()

Datum xmlcomment ( PG_FUNCTION_ARGS  )

Definition at line 471 of file xml.c.

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

472 {
473 #ifdef USE_LIBXML
474  text *arg = PG_GETARG_TEXT_PP(0);
475  char *argdata = VARDATA_ANY(arg);
476  int len = VARSIZE_ANY_EXHDR(arg);
478  int i;
479 
480  /* check for "--" in string or "-" at the end */
481  for (i = 1; i < len; i++)
482  {
483  if (argdata[i] == '-' && argdata[i - 1] == '-')
484  ereport(ERROR,
485  (errcode(ERRCODE_INVALID_XML_COMMENT),
486  errmsg("invalid XML comment")));
487  }
488  if (len > 0 && argdata[len - 1] == '-')
489  ereport(ERROR,
490  (errcode(ERRCODE_INVALID_XML_COMMENT),
491  errmsg("invalid XML comment")));
492 
493  initStringInfo(&buf);
494  appendStringInfoString(&buf, "<!--");
495  appendStringInfoText(&buf, arg);
496  appendStringInfoString(&buf, "-->");
497 
499 #else
500  NO_XML_SUPPORT();
501  return 0;
502 #endif
503 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4177
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define ereport(elevel, rest)
Definition: elog.h:141
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
int i
void * arg
Definition: c.h:556

◆ xmlconcat()

xmltype* xmlconcat ( List args)

Definition at line 512 of file xml.c.

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

Referenced by ExecEvalXmlExpr(), and xmlconcat2().

513 {
514 #ifdef USE_LIBXML
515  int global_standalone = 1;
516  xmlChar *global_version = NULL;
517  bool global_version_no_value = false;
519  ListCell *v;
520 
521  initStringInfo(&buf);
522  foreach(v, args)
523  {
525  size_t len;
526  xmlChar *version;
527  int standalone;
528  char *str;
529 
530  len = VARSIZE(x) - VARHDRSZ;
531  str = text_to_cstring((text *) x);
532 
533  parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
534 
535  if (standalone == 0 && global_standalone == 1)
536  global_standalone = 0;
537  if (standalone < 0)
538  global_standalone = -1;
539 
540  if (!version)
541  global_version_no_value = true;
542  else if (!global_version)
543  global_version = version;
544  else if (xmlStrcmp(version, global_version) != 0)
545  global_version_no_value = true;
546 
547  appendStringInfoString(&buf, str + len);
548  pfree(str);
549  }
550 
551  if (!global_version_no_value || global_standalone >= 0)
552  {
553  StringInfoData buf2;
554 
555  initStringInfo(&buf2);
556 
557  print_xml_decl(&buf2,
558  (!global_version_no_value) ? global_version : NULL,
559  0,
560  global_standalone);
561 
562  appendBinaryStringInfo(&buf2, buf.data, buf.len);
563  buf = buf2;
564  }
565 
566  return stringinfo_to_xmltype(&buf);
567 #else
568  NO_XML_SUPPORT();
569  return NULL;
570 #endif
571 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define VARSIZE(PTR)
Definition: postgres.h:303
#define PointerGetDatum(X)
Definition: postgres.h:556
#define VARHDRSZ
Definition: c.h:562
#define DatumGetXmlP(X)
Definition: xml.h:50
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:190
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
Definition: c.h:556
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ xmlconcat2()

Datum xmlconcat2 ( PG_FUNCTION_ARGS  )

Definition at line 578 of file xml.c.

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

579 {
580  if (PG_ARGISNULL(0))
581  {
582  if (PG_ARGISNULL(1))
583  PG_RETURN_NULL();
584  else
586  }
587  else if (PG_ARGISNULL(1))
589  else
591  PG_GETARG_XML_P(1))));
592 }
#define list_make2(x1, x2)
Definition: pg_list.h:229
xmltype * xmlconcat(List *args)
Definition: xml.c:512
#define PG_RETURN_XML_P(x)
Definition: xml.h:54
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ xmldata_root_element_end()

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

Definition at line 2668 of file xml.c.

References appendStringInfo().

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

2669 {
2670  appendStringInfo(result, "</%s>\n", eltname);
2671 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91

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

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

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

2644 {
2645  /* This isn't really wrong but currently makes no sense. */
2646  Assert(top_level || !xmlschema);
2647 
2648  appendStringInfo(result, "<%s", eltname);
2649  if (top_level)
2650  {
2651  appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2652  if (strlen(targetns) > 0)
2653  appendStringInfo(result, " xmlns=\"%s\"", targetns);
2654  }
2655  if (xmlschema)
2656  {
2657  /* FIXME: better targets */
2658  if (strlen(targetns) > 0)
2659  appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2660  else
2661  appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2662  }
2663  appendStringInfoString(result, ">\n");
2664 }
#define NAMESPACE_XSI
Definition: xml.c:229
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define Assert(condition)
Definition: c.h:739

◆ xmlelement()

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

Definition at line 628 of file xml.c.

References arg, XmlExpr::arg_names, XmlExpr::args, ERROR, exprType(), forboth, i, lappend(), lfirst, map_sql_value_to_xml_value(), XmlExpr::name, XmlExpr::named_args, NIL, NO_XML_SUPPORT, 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().

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

◆ xmlexists()

Datum xmlexists ( PG_FUNCTION_ARGS  )

Definition at line 4208 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, and PG_RETURN_BOOL.

4209 {
4210 #ifdef USE_LIBXML
4211  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4212  xmltype *data = PG_GETARG_XML_P(1);
4213  int res_nitems;
4214 
4215  xpath_internal(xpath_expr_text, data, NULL,
4216  &res_nitems, NULL);
4217 
4218  PG_RETURN_BOOL(res_nitems > 0);
4219 #else
4220  NO_XML_SUPPORT();
4221  return 0;
4222 #endif
4223 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: c.h:556

◆ xmlparse()

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

Definition at line 752 of file xml.c.

References GetDatabaseEncoding(), and NO_XML_SUPPORT.

Referenced by ExecEvalXmlExpr(), and texttoxml().

753 {
754 #ifdef USE_LIBXML
755  xmlDocPtr doc;
756 
757  doc = xml_parse(data, xmloption_arg, preserve_whitespace,
759  xmlFreeDoc(doc);
760 
761  return (xmltype *) data;
762 #else
763  NO_XML_SUPPORT();
764  return NULL;
765 #endif
766 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int GetDatabaseEncoding(void)
Definition: mbutils.c:1046
Definition: c.h:556

◆ xmlpi()

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

Definition at line 770 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

771 {
772 #ifdef USE_LIBXML
773  xmltype *result;
775 
776  if (pg_strcasecmp(target, "xml") == 0)
777  ereport(ERROR,
778  (errcode(ERRCODE_SYNTAX_ERROR), /* really */
779  errmsg("invalid XML processing instruction"),
780  errdetail("XML processing instruction target name cannot be \"%s\".", target)));
781 
782  /*
783  * Following the SQL standard, the null check comes after the syntax check
784  * above.
785  */
786  *result_is_null = arg_is_null;
787  if (*result_is_null)
788  return NULL;
789 
790  initStringInfo(&buf);
791 
792  appendStringInfo(&buf, "<?%s", target);
793 
794  if (arg != NULL)
795  {
796  char *string;
797 
798  string = text_to_cstring(arg);
799  if (strstr(string, "?>") != NULL)
800  ereport(ERROR,
801  (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
802  errmsg("invalid XML processing instruction"),
803  errdetail("XML processing instruction cannot contain \"?>\".")));
804 
805  appendStringInfoChar(&buf, ' ');
806  appendStringInfoString(&buf, string + strspn(string, " "));
807  pfree(string);
808  }
809  appendStringInfoString(&buf, "?>");
810 
811  result = stringinfo_to_xmltype(&buf);
812  pfree(buf.data);
813  return result;
814 #else
815  NO_XML_SUPPORT();
816  return NULL;
817 #endif
818 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:608
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
int errdetail(const char *fmt,...)
Definition: elog.c:955
char string[11]
Definition: preproc-type.c:46
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:822
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
Definition: c.h:556

◆ xmlroot()

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

Definition at line 822 of file xml.c.

References appendStringInfoString(), buf, initStringInfo(), 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().

823 {
824 #ifdef USE_LIBXML
825  char *str;
826  size_t len;
827  xmlChar *orig_version;
828  int orig_standalone;
830 
831  len = VARSIZE(data) - VARHDRSZ;
832  str = text_to_cstring((text *) data);
833 
834  parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
835 
836  if (version)
837  orig_version = xml_text2xmlChar(version);
838  else
839  orig_version = NULL;
840 
841  switch (standalone)
842  {
843  case XML_STANDALONE_YES:
844  orig_standalone = 1;
845  break;
846  case XML_STANDALONE_NO:
847  orig_standalone = 0;
848  break;
850  orig_standalone = -1;
851  break;
853  /* leave original value */
854  break;
855  }
856 
857  initStringInfo(&buf);
858  print_xml_decl(&buf, orig_version, 0, orig_standalone);
859  appendStringInfoString(&buf, str + len);
860 
861  return stringinfo_to_xmltype(&buf);
862 #else
863  NO_XML_SUPPORT();
864  return NULL;
865 #endif
866 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char * text_to_cstring(const text *t)
Definition: varlena.c:204
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
Definition: c.h:556

◆ XmlTableDestroyOpaque()

static void XmlTableDestroyOpaque ( struct TableFuncScanState state)
static

Definition at line 4751 of file xml.c.

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

4752 {
4753 #ifdef USE_LIBXML
4754  XmlTableBuilderData *xtCxt;
4755 
4756  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
4757 
4758  /* Propagate context related error context to libxml2 */
4759  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4760 
4761  if (xtCxt->xpathscomp != NULL)
4762  {
4763  int i;
4764 
4765  for (i = 0; i < xtCxt->natts; i++)
4766  if (xtCxt->xpathscomp[i] != NULL)
4767  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
4768  }
4769 
4770  if (xtCxt->xpathobj != NULL)
4771  xmlXPathFreeObject(xtCxt->xpathobj);
4772  if (xtCxt->xpathcomp != NULL)
4773  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
4774  if (xtCxt->xpathcxt != NULL)
4775  xmlXPathFreeContext(xtCxt->xpathcxt);
4776  if (xtCxt->doc != NULL)
4777  xmlFreeDoc(xtCxt->doc);
4778  if (xtCxt->ctxt != NULL)
4779  xmlFreeParserCtxt(xtCxt->ctxt);
4780 
4781  pg_xml_done(xtCxt->xmlerrcxt, true);
4782 
4783  /* not valid anymore */
4784  xtCxt->magic = 0;
4785  state->opaque = NULL;
4786 
4787 #else
4788  NO_XML_SUPPORT();
4789 #endif /* not USE_LIBXML */
4790 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
int i

◆ XmlTableFetchRow()

static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4548 of file xml.c.

References ERROR, NO_XML_SUPPORT, and xml_ereport().

4549 {
4550 #ifdef USE_LIBXML
4551  XmlTableBuilderData *xtCxt;
4552 
4553  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4554 
4555  /*
4556  * XmlTable returns table - set of composite values. The error context, is
4557  * used for producement more values, between two calls, there can be
4558  * created and used another libxml2 error context. It is libxml2 global
4559  * value, so it should be refreshed any time before any libxml2 usage,
4560  * that is finished by returning some value.
4561  */
4562  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4563 
4564  if (xtCxt->xpathobj == NULL)
4565  {
4566  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4567  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4568  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4569  "could not create XPath object");
4570 
4571  xtCxt->row_count = 0;
4572  }
4573 
4574  if (xtCxt->xpathobj->type == XPATH_NODESET)
4575  {
4576  if (xtCxt->xpathobj->nodesetval != NULL)
4577  {
4578  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4579  return true;
4580  }
4581  }
4582 
4583  return false;
4584 #else
4585  NO_XML_SUPPORT();
4586  return false;
4587 #endif /* not USE_LIBXML */
4588 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define ERROR
Definition: elog.h:43
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableGetValue()

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

Definition at line 4599 of file xml.c.

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

4601 {
4602 #ifdef USE_LIBXML
4603  XmlTableBuilderData *xtCxt;
4604  Datum result = (Datum) 0;
4605  xmlNodePtr cur;
4606  char *cstr = NULL;
4607  volatile xmlXPathObjectPtr xpathobj = NULL;
4608 
4609  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4610 
4611  Assert(xtCxt->xpathobj &&
4612  xtCxt->xpathobj->type == XPATH_NODESET &&
4613  xtCxt->xpathobj->nodesetval != NULL);
4614 
4615  /* Propagate context related error context to libxml2 */
4616  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4617 
4618  *isnull = false;
4619 
4620  cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
4621 
4622  Assert(xtCxt->xpathscomp[colnum] != NULL);
4623 
4624  PG_TRY();
4625  {
4626  /* Set current node as entry point for XPath evaluation */
4627  xtCxt->xpathcxt->node = cur;
4628 
4629  /* Evaluate column path */
4630  xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
4631  if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4632  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4633  "could not create XPath object");
4634 
4635  /*
4636  * There are four possible cases, depending on the number of nodes
4637  * returned by the XPath expression and the type of the target column:
4638  * a) XPath returns no nodes. b) The target type is XML (return all
4639  * as XML). For non-XML return types: c) One node (return content).
4640  * d) Multiple nodes (error).
4641  */
4642  if (xpathobj->type == XPATH_NODESET)
4643  {
4644  int count = 0;
4645 
4646  if (xpathobj->nodesetval != NULL)
4647  count = xpathobj->nodesetval->nodeNr;
4648 
4649  if (xpathobj->nodesetval == NULL || count == 0)
4650  {
4651  *isnull = true;
4652  }
4653  else
4654  {
4655  if (typid == XMLOID)
4656  {
4657  text *textstr;
4659 
4660  /* Concatenate serialized values */
4661  initStringInfo(&str);
4662  for (int i = 0; i < count; i++)
4663  {
4664  textstr =
4665  xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
4666  xtCxt->xmlerrcxt);
4667 
4668  appendStringInfoText(&str, textstr);
4669  }
4670  cstr = str.data;
4671  }
4672  else
4673  {
4674  xmlChar *str;
4675 
4676  if (count > 1)
4677  ereport(ERROR,
4678  (errcode(ERRCODE_CARDINALITY_VIOLATION),
4679  errmsg("more than one value returned by column XPath expression")));
4680 
4681  str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);
4682  cstr = str ? xml_pstrdup_and_free(str) : "";
4683  }
4684  }
4685  }
4686  else if (xpathobj->type == XPATH_STRING)
4687  {
4688  /* Content should be escaped when target will be XML */
4689  if (typid == XMLOID)
4690  cstr = escape_xml((char *) xpathobj->stringval);
4691  else
4692  cstr = (char *) xpathobj->stringval;
4693  }
4694  else if (xpathobj->type == XPATH_BOOLEAN)
4695  {
4696  char typcategory;
4697  bool typispreferred;
4698  xmlChar *str;
4699 
4700  /* Allow implicit casting from boolean to numbers */
4701  get_type_category_preferred(typid, &typcategory, &typispreferred);
4702 
4703  if (typcategory != TYPCATEGORY_NUMERIC)
4704  str = xmlXPathCastBooleanToString(xpathobj->boolval);
4705  else
4706  str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval));
4707 
4708  cstr = xml_pstrdup_and_free(str);
4709  }
4710  else if (xpathobj->type == XPATH_NUMBER)
4711  {
4712  xmlChar *str;
4713 
4714  str = xmlXPathCastNumberToString(xpathobj->floatval);
4715  cstr = xml_pstrdup_and_free(str);
4716  }
4717  else
4718  elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
4719 
4720  /*
4721  * By here, either cstr contains the result value, or the isnull flag
4722  * has been set.
4723  */
4724  Assert(cstr || *isnull);
4725 
4726  if (!*isnull)
4727  result = InputFunctionCall(&state->in_functions[colnum],
4728  cstr,
4729  state->typioparams[colnum],
4730  typmod);
4731  }
4732  PG_FINALLY();
4733  {
4734  if (xpathobj != NULL)
4735  xmlXPathFreeObject(xpathobj);
4736  }
4737  PG_END_TRY();
4738 
4739  return result;
4740 #else
4741  NO_XML_SUPPORT();
4742  return 0;
4743 #endif /* not USE_LIBXML */
4744 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4177
#define ereport(elevel, rest)
Definition: elog.h:141
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define PG_FINALLY()
Definition: elog.h:339
uintptr_t Datum
Definition: postgres.h:367
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1531
#define Assert(condition)
Definition: c.h:739
FmgrInfo * in_functions
Definition: execnodes.h:1710
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
int i
Definition: c.h:556
char * escape_xml(const char *str)
Definition: xml.c:2371
#define PG_TRY()
Definition: elog.h:322
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2478
#define PG_END_TRY()
Definition: elog.h:347
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableInitOpaque()

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

Definition at line 4356 of file xml.c.

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

4357 {
4358 #ifdef USE_LIBXML
4359  volatile xmlParserCtxtPtr ctxt = NULL;
4360  XmlTableBuilderData *xtCxt;
4361  PgXmlErrorContext *xmlerrcxt;
4362 
4363  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4364  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4365  xtCxt->natts = natts;
4366  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4367 
4368  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4369 
4370  PG_TRY();
4371  {
4372  xmlInitParser();
4373 
4374  ctxt = xmlNewParserCtxt();
4375  if (ctxt == NULL || xmlerrcxt->err_occurred)
4376  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4377  "could not allocate parser context");
4378  }
4379  PG_CATCH();
4380  {
4381  if (ctxt != NULL)
4382  xmlFreeParserCtxt(ctxt);
4383 
4384  pg_xml_done(xmlerrcxt, true);
4385 
4386  PG_RE_THROW();
4387  }
4388  PG_END_TRY();
4389 
4390  xtCxt->xmlerrcxt = xmlerrcxt;
4391  xtCxt->ctxt = ctxt;
4392 
4393  state->opaque = xtCxt;
4394 #else
4395  NO_XML_SUPPORT();
4396 #endif /* not USE_LIBXML */
4397 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
#define ERROR
Definition: elog.h:43
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
void * palloc0(Size size)
Definition: mcxt.c:980
#define PG_CATCH()
Definition: elog.h:332
#define PG_RE_THROW()
Definition: elog.h:363
#define PG_TRY()
Definition: elog.h:322
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:347
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableSetColumnFilter()

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

Definition at line 4516 of file xml.c.

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

4517 {
4518 #ifdef USE_LIBXML
4519  XmlTableBuilderData *xtCxt;
4520  xmlChar *xstr;
4521 
4522  AssertArg(PointerIsValid(path));
4523 
4524  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4525 
4526  if (*path == '\0')
4527  ereport(ERROR,
4528  (errcode(ERRCODE_DATA_EXCEPTION),
4529  errmsg("column path filter must not be empty string")));
4530 
4531  xstr = pg_xmlCharStrndup(path, strlen(path));
4532 
4533  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4534  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4535  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4536  "invalid XPath expression");
4537 #else
4538  NO_XML_SUPPORT();
4539 #endif /* not USE_LIBXML */
4540 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define AssertArg(condition)
Definition: c.h:741
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define PointerIsValid(pointer)
Definition: c.h:633
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableSetDocument()

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

Definition at line 4404 of file xml.c.

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

4405 {
4406 #ifdef USE_LIBXML
4407  XmlTableBuilderData *xtCxt;
4408  xmltype *xmlval = DatumGetXmlP(value);
4409  char *str;
4410  xmlChar *xstr;
4411  int length;
4412  volatile xmlDocPtr doc = NULL;
4413  volatile xmlXPathContextPtr xpathcxt = NULL;
4414 
4415  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4416 
4417  /*
4418  * Use out function for casting to string (remove encoding property). See
4419  * comment in xml_out.
4420  */
4421  str = xml_out_internal(xmlval, 0);
4422 
4423  length = strlen(str);
4424  xstr = pg_xmlCharStrndup(str, length);
4425 
4426  PG_TRY();
4427  {
4428  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4429  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4430  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4431  "could not parse XML document");
4432  xpathcxt = xmlXPathNewContext(doc);
4433  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4434  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4435  "could not allocate XPath context");
4436  xpathcxt->node = (xmlNodePtr) doc;
4437  }
4438  PG_CATCH();
4439  {
4440  if (xpathcxt != NULL)
4441  xmlXPathFreeContext(xpathcxt);
4442  if (doc != NULL)
4443  xmlFreeDoc(doc);
4444 
4445  PG_RE_THROW();
4446  }
4447  PG_END_TRY();
4448 
4449  xtCxt->doc = doc;
4450  xtCxt->xpathcxt = xpathcxt;
4451 #else
4452  NO_XML_SUPPORT();
4453 #endif /* not USE_LIBXML */
4454 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
static struct @145 value
#define DatumGetXmlP(X)
Definition: xml.h:50
#define ERROR
Definition: elog.h:43
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:293
#define PG_CATCH()
Definition: elog.h:332
#define PG_RE_THROW()
Definition: elog.h:363
Definition: c.h:556
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableSetNamespace()

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

Definition at line 4461 of file xml.c.

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

4462 {
4463 #ifdef USE_LIBXML
4464  XmlTableBuilderData *xtCxt;
4465 
4466  if (name == NULL)
4467  ereport(ERROR,
4468  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4469  errmsg("DEFAULT namespace is not supported")));
4470  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4471 
4472  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4473  pg_xmlCharStrndup(name, strlen(name)),
4474  pg_xmlCharStrndup(uri, strlen(uri))))
4475  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4476  "could not set XML namespace");
4477 #else
4478  NO_XML_SUPPORT();
4479 #endif /* not USE_LIBXML */
4480 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:822
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ XmlTableSetRowFilter()

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

Definition at line 4487 of file xml.c.

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

4488 {
4489 #ifdef USE_LIBXML
4490  XmlTableBuilderData *xtCxt;
4491  xmlChar *xstr;
4492 
4493  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4494 
4495  if (*path == '\0')
4496  ereport(ERROR,
4497  (errcode(ERRCODE_DATA_EXCEPTION),
4498  errmsg("row path filter must not be empty string")));
4499 
4500  xstr = pg_xmlCharStrndup(path, strlen(path));
4501 
4502  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4503  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4504  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4505  "invalid XPath expression");
4506 #else
4507  NO_XML_SUPPORT();
4508 #endif /* not USE_LIBXML */
4509 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ xmltotext()

Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 605 of file xml.c.

References PG_GETARG_XML_P, and PG_RETURN_TEXT_P.

606 {
607  xmltype *data = PG_GETARG_XML_P(0);
608 
609  /* It's actually binary compatible. */
610  PG_RETURN_TEXT_P((text *) data);
611 }
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
Definition: c.h:556

◆ xmltotext_with_xmloption()

text* xmltotext_with_xmloption ( xmltype data,
XmlOptionType  xmloption_arg 
)

Definition at line 615 of file xml.c.

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

Referenced by ExecEvalXmlExpr().

616 {
617  if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data))
618  ereport(ERROR,
619  (errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
620  errmsg("not an XML document")));
621 
622  /* It's actually binary compatible, save for the above check. */
623  return (text *) data;
624 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool xml_is_document(xmltype *arg)
Definition: xml.c:888
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:556

◆ xmlvalidate()

Datum xmlvalidate ( PG_FUNCTION_ARGS  )

Definition at line 878 of file xml.c.

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

879 {
880  ereport(ERROR,
881  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
882  errmsg("xmlvalidate is not implemented")));
883  return 0;
884 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4185 of file xml.c.

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

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

4186 {
4187 #ifdef USE_LIBXML
4188  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4189  xmltype *data = PG_GETARG_XML_P(1);
4190  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4191  ArrayBuildState *astate;
4192 
4193  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4194  xpath_internal(xpath_expr_text, data, namespaces,
4195  NULL, astate);
4197 #else
4198  NO_XML_SUPPORT();
4199  return 0;
4200 #endif
4201 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5014
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:253
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5117
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
Definition: c.h:556

◆ xpath_exists()

Datum xpath_exists ( PG_FUNCTION_ARGS  )

Definition at line 4231 of file xml.c.

References FlushErrorState(), GetDatabaseEncoding(), NO_XML_SUPPORT, PG_CATCH, PG_END_TRY, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, PG_RETURN_BOOL, and PG_TRY.

4232 {
4233 #ifdef USE_LIBXML
4234  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4235  xmltype *data = PG_GETARG_XML_P(1);
4236  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4237  int res_nitems;
4238 
4239  xpath_internal(xpath_expr_text, data, namespaces,
4240  &res_nitems, NULL);
4241 
4242  PG_RETURN_BOOL(res_nitems > 0);
4243 #else
4244  NO_XML_SUPPORT();
4245  return 0;
4246 #endif
4247 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define PG_GETARG_XML_P(n)
Definition: xml.h:53
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: c.h:556

◆ xsd_schema_element_end()

static void xsd_schema_element_end ( StringInfo  result)
static

Definition at line 2933 of file xml.c.

References appendStringInfoString().

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

2934 {
2935  appendStringInfoString(result, "</xsd:schema>");
2936 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176

◆ xsd_schema_element_start()

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

Definition at line 2916 of file xml.c.

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

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

2917 {
2918  appendStringInfoString(result,
2919  "<xsd:schema\n"
2920  " xmlns:xsd=\"" NAMESPACE_XSD "\"");
2921  if (strlen(targetns) > 0)
2922  appendStringInfo(result,
2923  "\n"
2924  " targetNamespace=\"%s\"\n"
2925  " elementFormDefault=\"qualified\"",
2926  targetns);
2927  appendStringInfoString(result,
2928  ">\n\n");
2929 }
#define NAMESPACE_XSD
Definition: xml.c:228
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176

Variable Documentation

◆ xmlbinary

int xmlbinary

Definition at line 97 of file xml.c.

Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().

◆ xmloption

◆ XmlTableRoutine

const TableFuncRoutine XmlTableRoutine
Initial value:
=
{
}
static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts)
Definition: xml.c:4356
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4548
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4461
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4404
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4516
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4599
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4487
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:4751

Definition at line 207 of file xml.c.

Referenced by ExecInitTableFuncScan().