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:974
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

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

Function Documentation

◆ _SPI_strdup()

static char* _SPI_strdup ( const char *  s)
static

Definition at line 2405 of file xml.c.

References SPI_palloc().

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

2406 {
2407  size_t len = strlen(s) + 1;
2408  char *ret = SPI_palloc(len);
2409 
2410  memcpy(ret, s, len);
2411  return ret;
2412 }
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:549

◆ cursor_to_xml()

Datum cursor_to_xml ( PG_FUNCTION_ARGS  )

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

2586 {
2589  bool nulls = PG_GETARG_BOOL(2);
2590  bool tableforest = PG_GETARG_BOOL(3);
2591  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2592 
2593  StringInfoData result;
2594  Portal portal;
2595  uint64 i;
2596 
2597  initStringInfo(&result);
2598 
2599  if (!tableforest)
2600  {
2601  xmldata_root_element_start(&result, "table", NULL, targetns, true);
2602  appendStringInfoChar(&result, '\n');
2603  }
2604 
2605  SPI_connect();
2606  portal = SPI_cursor_find(name);
2607  if (portal == NULL)
2608  ereport(ERROR,
2609  (errcode(ERRCODE_UNDEFINED_CURSOR),
2610  errmsg("cursor \"%s\" does not exist", name)));
2611 
2612  SPI_cursor_fetch(portal, true, count);
2613  for (i = 0; i < SPI_processed; i++)
2614  SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2615  tableforest, targetns, true);
2616 
2617  SPI_finish();
2618 
2619  if (!tableforest)
2620  xmldata_root_element_end(&result, "table");
2621 
2623 }
#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:2639
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
uint64 SPI_processed
Definition: spi.c:45
signed int int32
Definition: c.h:346
#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:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2666
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:784
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:3754

◆ cursor_to_xmlschema()

Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

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

2767 {
2769  bool nulls = PG_GETARG_BOOL(1);
2770  bool tableforest = PG_GETARG_BOOL(2);
2771  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2772  const char *xmlschema;
2773  Portal portal;
2774 
2775  SPI_connect();
2776  portal = SPI_cursor_find(name);
2777  if (portal == NULL)
2778  ereport(ERROR,
2779  (errcode(ERRCODE_UNDEFINED_CURSOR),
2780  errmsg("cursor \"%s\" does not exist", name)));
2781 
2782  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2783  InvalidOid, nulls,
2784  tableforest, targetns));
2785  SPI_finish();
2786 
2787  PG_RETURN_XML_P(cstring_to_xmltype(xmlschema));
2788 }
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:2405
#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:3184
#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:784

◆ database_get_xml_visible_schemas()

static List* database_get_xml_visible_schemas ( void  )
static

Definition at line 2514 of file xml.c.

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

2515 {
2516  return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2517 }
static List * query_to_oid_list(const char *query)
Definition: xml.c:2462
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2510

◆ database_get_xml_visible_tables()

static List* database_get_xml_visible_tables ( void  )
static

Definition at line 2521 of file xml.c.

References CppAsString2, query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xmlschema_internal().

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

◆ database_to_xml()

Datum database_to_xml ( PG_FUNCTION_ARGS  )

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

3068 {
3069  bool nulls = PG_GETARG_BOOL(0);
3070  bool tableforest = PG_GETARG_BOOL(1);
3071  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3072 
3074  tableforest, targetns)));
3075 }
#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:3024
#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 3134 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().

3135 {
3136  bool nulls = PG_GETARG_BOOL(0);
3137  bool tableforest = PG_GETARG_BOOL(1);
3138  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3139  StringInfo xmlschema;
3140 
3141  xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3142 
3144  nulls, tableforest, targetns)));
3145 }
#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:3024
#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:3079
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 3024 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().

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

◆ database_to_xmlschema()

Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

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

3123 {
3124  bool nulls = PG_GETARG_BOOL(0);
3125  bool tableforest = PG_GETARG_BOOL(1);
3126  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3127 
3129  tableforest, targetns)));
3130 }
#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:3079
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 3079 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().

3081 {
3082  List *relid_list;
3083  List *nspid_list;
3084  List *tupdesc_list;
3085  ListCell *cell;
3086  StringInfo result;
3087 
3088  result = makeStringInfo();
3089 
3090  xsd_schema_element_start(result, targetns);
3091 
3092  SPI_connect();
3093 
3094  relid_list = database_get_xml_visible_tables();
3095  nspid_list = database_get_xml_visible_schemas();
3096 
3097  tupdesc_list = NIL;
3098  foreach(cell, relid_list)
3099  {
3100  Relation rel;
3101 
3102  rel = table_open(lfirst_oid(cell), AccessShareLock);
3103  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3104  table_close(rel, NoLock);
3105  }
3106 
3107  appendStringInfoString(result,
3108  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
3109 
3110  appendStringInfoString(result,
3111  map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3112 
3113  xsd_schema_element_end(result);
3114 
3115  SPI_finish();
3116 
3117  return result;
3118 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2914
#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:28
#define AccessShareLock
Definition: lockdefs.h:36
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3362
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:321
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3524
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2514
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2931
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:2521

◆ escape_xml()

char* escape_xml ( const char *  str)

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

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

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

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

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

3364 {
3365  char *dbname;
3366  char *xmlcn;
3367  char *catalogtypename;
3368  StringInfoData result;
3369  ListCell *cell;
3370 
3371  dbname = get_database_name(MyDatabaseId);
3372 
3373  initStringInfo(&result);
3374 
3375  xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3376 
3377  catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3378  dbname,
3379  NULL,
3380  NULL);
3381 
3382  appendStringInfo(&result,
3383  "<xsd:complexType name=\"%s\">\n", catalogtypename);
3384  appendStringInfoString(&result,
3385  " <xsd:all>\n");
3386 
3387  foreach(cell, nspid_list)
3388  {
3389  Oid nspid = lfirst_oid(cell);
3390  char *nspname = get_namespace_name(nspid);
3391  char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3392  char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3393  dbname,
3394  nspname,
3395  NULL);
3396 
3397  appendStringInfo(&result,
3398  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3399  xmlsn, schematypename);
3400  }
3401 
3402  appendStringInfoString(&result,
3403  " </xsd:all>\n");
3404  appendStringInfoString(&result,
3405  "</xsd:complexType>\n\n");
3406 
3407  appendStringInfo(&result,
3408  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3409  xmlcn, catalogtypename);
3410 
3411  return result.data;
3412 }
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
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:2038
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:3153
char * dbname
Definition: streamutil.c:52
#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 2038 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().

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

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

3291 {
3292  char *dbname;
3293  char *nspname;
3294  char *xmlsn;
3295  char *schematypename;
3296  StringInfoData result;
3297  ListCell *cell;
3298 
3299  dbname = get_database_name(MyDatabaseId);
3300  nspname = get_namespace_name(nspid);
3301 
3302  initStringInfo(&result);
3303 
3304  xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3305 
3306  schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3307  dbname,
3308  nspname,
3309  NULL);
3310 
3311  appendStringInfo(&result,
3312  "<xsd:complexType name=\"%s\">\n", schematypename);
3313  if (!tableforest)
3314  appendStringInfoString(&result,
3315  " <xsd:all>\n");
3316  else
3317  appendStringInfoString(&result,
3318  " <xsd:sequence>\n");
3319 
3320  foreach(cell, relid_list)
3321  {
3322  Oid relid = lfirst_oid(cell);
3323  char *relname = get_rel_name(relid);
3324  char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3325  char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3326  dbname,
3327  nspname,
3328  relname);
3329 
3330  if (!tableforest)
3331  appendStringInfo(&result,
3332  " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3333  xmltn, tabletypename);
3334  else
3335  appendStringInfo(&result,
3336  " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3337  xmltn, tabletypename);
3338  }
3339 
3340  if (!tableforest)
3341  appendStringInfoString(&result,
3342  " </xsd:all>\n");
3343  else
3344  appendStringInfoString(&result,
3345  " </xsd:sequence>\n");
3346  appendStringInfoString(&result,
3347  "</xsd:complexType>\n\n");
3348 
3349  appendStringInfo(&result,
3350  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3351  xmlsn, schematypename);
3352 
3353  return result.data;
3354 }
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:78
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
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:2038
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:3153
char * dbname
Definition: streamutil.c:52
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 3184 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().

3186 {
3187  int i;
3188  char *xmltn;
3189  char *tabletypename;
3190  char *rowtypename;
3191  StringInfoData result;
3192 
3193  initStringInfo(&result);
3194 
3195  if (OidIsValid(relid))
3196  {
3197  HeapTuple tuple;
3198  Form_pg_class reltuple;
3199 
3200  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3201  if (!HeapTupleIsValid(tuple))
3202  elog(ERROR, "cache lookup failed for relation %u", relid);
3203  reltuple = (Form_pg_class) GETSTRUCT(tuple);
3204 
3205  xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3206  true, false);
3207 
3208  tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3210  get_namespace_name(reltuple->relnamespace),
3211  NameStr(reltuple->relname));
3212 
3213  rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3215  get_namespace_name(reltuple->relnamespace),
3216  NameStr(reltuple->relname));
3217 
3218  ReleaseSysCache(tuple);
3219  }
3220  else
3221  {
3222  if (tableforest)
3223  xmltn = "row";
3224  else
3225  xmltn = "table";
3226 
3227  tabletypename = "TableType";
3228  rowtypename = "RowType";
3229  }
3230 
3231  xsd_schema_element_start(&result, targetns);
3232 
3233  appendStringInfoString(&result,
3235 
3236  appendStringInfo(&result,
3237  "<xsd:complexType name=\"%s\">\n"
3238  " <xsd:sequence>\n",
3239  rowtypename);
3240 
3241  for (i = 0; i < tupdesc->natts; i++)
3242  {
3243  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3244 
3245  if (att->attisdropped)
3246  continue;
3247  appendStringInfo(&result,
3248  " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3250  true, false),
3251  map_sql_type_to_xml_name(att->atttypid, -1),
3252  nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3253  }
3254 
3255  appendStringInfoString(&result,
3256  " </xsd:sequence>\n"
3257  "</xsd:complexType>\n\n");
3258 
3259  if (!tableforest)
3260  {
3261  appendStringInfo(&result,
3262  "<xsd:complexType name=\"%s\">\n"
3263  " <xsd:sequence>\n"
3264  " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3265  " </xsd:sequence>\n"
3266  "</xsd:complexType>\n\n",
3267  tabletypename, rowtypename);
3268 
3269  appendStringInfo(&result,
3270  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3271  xmltn, tabletypename);
3272  }
3273  else
3274  appendStringInfo(&result,
3275  "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3276  xmltn, rowtypename);
3277 
3278  xsd_schema_element_end(&result);
3279 
3280  return result.data;
3281 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2914
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define OidIsValid(objectId)
Definition: c.h:638
#define list_make1(x1)
Definition: pg_list.h:227
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
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:2038
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:3524
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3419
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2931
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:3153
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
#define elog(elevel,...)
Definition: elog.h:226
int i
#define NameStr(name)
Definition: c.h:609

◆ map_sql_type_to_xml_name()

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

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

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

◆ map_sql_type_to_xmlschema_type()

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

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

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

◆ map_sql_typecoll_to_xmlschema_types()

static const char * map_sql_typecoll_to_xmlschema_types ( List tupdesc_list)
static

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

3525 {
3526  List *uniquetypes = NIL;
3527  int i;
3528  StringInfoData result;
3529  ListCell *cell0;
3530 
3531  /* extract all column types used in the set of TupleDescs */
3532  foreach(cell0, tupdesc_list)
3533  {
3534  TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3535 
3536  for (i = 0; i < tupdesc->natts; i++)
3537  {
3538  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3539 
3540  if (att->attisdropped)
3541  continue;
3542  uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3543  }
3544  }
3545 
3546  /* add base types of domains */
3547  foreach(cell0, uniquetypes)
3548  {
3549  Oid typid = lfirst_oid(cell0);
3550  Oid basetypid = getBaseType(typid);
3551 
3552  if (basetypid != typid)
3553  uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3554  }
3555 
3556  /* Convert to textual form */
3557  initStringInfo(&result);
3558 
3559  foreach(cell0, uniquetypes)
3560  {
3561  appendStringInfo(&result, "%s\n",
3563  -1));
3564  }
3565 
3566  return result.data;
3567 }
#define NIL
Definition: pg_list.h:65
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1214
#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:78
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#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:3579
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 2154 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().

2155 {
2157  {
2158  ArrayType *array;
2159  Oid elmtype;
2160  int16 elmlen;
2161  bool elmbyval;
2162  char elmalign;
2163  int num_elems;
2164  Datum *elem_values;
2165  bool *elem_nulls;
2167  int i;
2168 
2169  array = DatumGetArrayTypeP(value);
2170  elmtype = ARR_ELEMTYPE(array);
2171  get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2172 
2173  deconstruct_array(array, elmtype,
2174  elmlen, elmbyval, elmalign,
2175  &elem_values, &elem_nulls,
2176  &num_elems);
2177 
2178  initStringInfo(&buf);
2179 
2180  for (i = 0; i < num_elems; i++)
2181  {
2182  if (elem_nulls[i])
2183  continue;
2184  appendStringInfoString(&buf, "<element>");
2186  map_sql_value_to_xml_value(elem_values[i],
2187  elmtype, true));
2188  appendStringInfoString(&buf, "</element>");
2189  }
2190 
2191  pfree(elem_values);
2192  pfree(elem_nulls);
2193 
2194  return buf.data;
2195  }
2196  else
2197  {
2198  Oid typeOut;
2199  bool isvarlena;
2200  char *str;
2201 
2202  /*
2203  * Flatten domains; the special-case treatments below should apply to,
2204  * eg, domains over boolean not just boolean.
2205  */
2206  type = getBaseType(type);
2207 
2208  /*
2209  * Special XSD formatting for some data types
2210  */
2211  switch (type)
2212  {
2213  case BOOLOID:
2214  if (DatumGetBool(value))
2215  return "true";
2216  else
2217  return "false";
2218 
2219  case DATEOID:
2220  {
2221  DateADT date;
2222  struct pg_tm tm;
2223  char buf[MAXDATELEN + 1];
2224 
2225  date = DatumGetDateADT(value);
2226  /* XSD doesn't support infinite values */
2227  if (DATE_NOT_FINITE(date))
2228  ereport(ERROR,
2229  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2230  errmsg("date out of range"),
2231  errdetail("XML does not support infinite date values.")));
2233  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2235 
2236  return pstrdup(buf);
2237  }
2238 
2239  case TIMESTAMPOID:
2240  {
2242  struct pg_tm tm;
2243  fsec_t fsec;
2244  char buf[MAXDATELEN + 1];
2245 
2246  timestamp = DatumGetTimestamp(value);
2247 
2248  /* XSD doesn't support infinite values */
2249  if (TIMESTAMP_NOT_FINITE(timestamp))
2250  ereport(ERROR,
2251  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2252  errmsg("timestamp out of range"),
2253  errdetail("XML does not support infinite timestamp values.")));
2254  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2255  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2256  else
2257  ereport(ERROR,
2258  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2259  errmsg("timestamp out of range")));
2260 
2261  return pstrdup(buf);
2262  }
2263 
2264  case TIMESTAMPTZOID:
2265  {
2267  struct pg_tm tm;
2268  int tz;
2269  fsec_t fsec;
2270  const char *tzn = NULL;
2271  char buf[MAXDATELEN + 1];
2272 
2273  timestamp = DatumGetTimestamp(value);
2274 
2275  /* XSD doesn't support infinite values */
2276  if (TIMESTAMP_NOT_FINITE(timestamp))
2277  ereport(ERROR,
2278  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2279  errmsg("timestamp out of range"),
2280  errdetail("XML does not support infinite timestamp values.")));
2281  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2282  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2283  else
2284  ereport(ERROR,
2285  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2286  errmsg("timestamp out of range")));
2287 
2288  return pstrdup(buf);
2289  }
2290 
2291 #ifdef USE_LIBXML
2292  case BYTEAOID:
2293  {
2294  bytea *bstr = DatumGetByteaPP(value);
2295  PgXmlErrorContext *xmlerrcxt;
2296  volatile xmlBufferPtr buf = NULL;
2297  volatile xmlTextWriterPtr writer = NULL;
2298  char *result;
2299 
2300  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
2301 
2302  PG_TRY();
2303  {
2304  buf = xmlBufferCreate();
2305  if (buf == NULL || xmlerrcxt->err_occurred)
2306  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2307  "could not allocate xmlBuffer");
2308  writer = xmlNewTextWriterMemory(buf, 0);
2309  if (writer == NULL || xmlerrcxt->err_occurred)
2310  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2311  "could not allocate xmlTextWriter");
2312 
2313  if (xmlbinary == XMLBINARY_BASE64)
2314  xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2315  0, VARSIZE_ANY_EXHDR(bstr));
2316  else
2317  xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2318  0, VARSIZE_ANY_EXHDR(bstr));
2319 
2320  /* we MUST do this now to flush data out to the buffer */
2321  xmlFreeTextWriter(writer);
2322  writer = NULL;
2323 
2324  result = pstrdup((const char *) xmlBufferContent(buf));
2325  }
2326  PG_CATCH();
2327  {
2328  if (writer)
2329  xmlFreeTextWriter(writer);
2330  if (buf)
2331  xmlBufferFree(buf);
2332 
2333  pg_xml_done(xmlerrcxt, true);
2334 
2335  PG_RE_THROW();
2336  }
2337  PG_END_TRY();
2338 
2339  xmlBufferFree(buf);
2340 
2341  pg_xml_done(xmlerrcxt, false);
2342 
2343  return result;
2344  }
2345 #endif /* USE_LIBXML */
2346 
2347  }
2348 
2349  /*
2350  * otherwise, just use the type's native text representation
2351  */
2352  getTypeOutputInfo(type, &typeOut, &isvarlena);
2353  str = OidOutputFunctionCall(typeOut, value);
2354 
2355  /* ... exactly as-is for XML, and when escaping is not wanted */
2356  if (type == XMLOID || !xml_escape_strings)
2357  return str;
2358 
2359  /* otherwise, translate special characters as needed */
2360  return escape_xml(str);
2361  }
2362 }
#define MAXDATELEN
Definition: datetime.h:201
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3858
signed short int16
Definition: c.h:345
#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:1161
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1777
static struct @144 value
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:1031
#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:163
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:68
int tm_mon
Definition: pgtime.h:31
int errdetail(const char *fmt,...)
Definition: elog.c:860
#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:3973
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:295
int64 Timestamp
Definition: timestamp.h:38
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uintptr_t Datum
Definition: postgres.h:367
#define PG_CATCH()
Definition: elog.h:310
#define PG_RE_THROW()
Definition: elog.h:331
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:784
int i
Definition: c.h:549
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
char * escape_xml(const char *str)
Definition: xml.c:2373
#define PG_TRY()
Definition: elog.h:301
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2154
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:317
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 2114 of file xml.c.

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

Referenced by get_rule_expr().

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

◆ query_to_oid_list()

static List* query_to_oid_list ( const char *  query)
static

Definition at line 2462 of file xml.c.

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

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

2463 {
2464  uint64 i;
2465  List *list = NIL;
2466 
2467  SPI_execute(query, true, 0);
2468 
2469  for (i = 0; i < SPI_processed; i++)
2470  {
2471  Datum oid;
2472  bool isnull;
2473 
2474  oid = SPI_getbinval(SPI_tuptable->vals[i],
2476  1,
2477  &isnull);
2478  if (!isnull)
2479  list = lappend_oid(list, DatumGetObjectId(oid));
2480  }
2481 
2482  return list;
2483 }
#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:357
uint64 SPI_processed
Definition: spi.c:45
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1028
uintptr_t Datum
Definition: postgres.h:367
TupleDesc tupdesc
Definition: spi.h:25
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 2571 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().

2572 {
2573  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2574  bool nulls = PG_GETARG_BOOL(1);
2575  bool tableforest = PG_GETARG_BOOL(2);
2576  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2577 
2579  NULL, nulls, tableforest,
2580  targetns, true)));
2581 }
#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:2673
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 2813 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.

2814 {
2815  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2816  bool nulls = PG_GETARG_BOOL(1);
2817  bool tableforest = PG_GETARG_BOOL(2);
2818  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2819 
2820  const char *xmlschema;
2821  SPIPlanPtr plan;
2822  Portal portal;
2823 
2824  SPI_connect();
2825 
2826  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2827  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2828 
2829  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2830  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2831 
2832  xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc,
2833  InvalidOid, nulls, tableforest, targetns));
2834  SPI_cursor_close(portal);
2835  SPI_finish();
2836 
2838  xmlschema, nulls, tableforest,
2839  targetns, true)));
2840 }
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:2405
#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:3184
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:2673
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:226

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

2676 {
2677  StringInfo result;
2678  char *xmltn;
2679  uint64 i;
2680 
2681  if (tablename)
2682  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
2683  else
2684  xmltn = "table";
2685 
2686  result = makeStringInfo();
2687 
2688  SPI_connect();
2689  if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
2690  ereport(ERROR,
2691  (errcode(ERRCODE_DATA_EXCEPTION),
2692  errmsg("invalid query")));
2693 
2694  if (!tableforest)
2695  {
2696  xmldata_root_element_start(result, xmltn, xmlschema,
2697  targetns, top_level);
2698  appendStringInfoChar(result, '\n');
2699  }
2700 
2701  if (xmlschema)
2702  appendStringInfo(result, "%s\n\n", xmlschema);
2703 
2704  for (i = 0; i < SPI_processed; i++)
2705  SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
2706  tableforest, targetns, top_level);
2707 
2708  if (!tableforest)
2709  xmldata_root_element_end(result, xmltn);
2710 
2711  SPI_finish();
2712 
2713  return result;
2714 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2639
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
int errcode(int sqlerrcode)
Definition: elog.c:570
uint64 SPI_processed
Definition: spi.c:45
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#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:2038
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
#define SPI_OK_SELECT
Definition: spi.h:57
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2666
int errmsg(const char *fmt,...)
Definition: elog.c:784
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:3754
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 2737 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.

2738 {
2739  char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2740  bool nulls = PG_GETARG_BOOL(1);
2741  bool tableforest = PG_GETARG_BOOL(2);
2742  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2743  const char *result;
2744  SPIPlanPtr plan;
2745  Portal portal;
2746 
2747  SPI_connect();
2748 
2749  if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
2750  elog(ERROR, "SPI_prepare(\"%s\") failed", query);
2751 
2752  if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
2753  elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
2754 
2756  InvalidOid, nulls,
2757  tableforest, targetns));
2758  SPI_cursor_close(portal);
2759  SPI_finish();
2760 
2762 }
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:2405
#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:3184
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:226

◆ schema_get_xml_visible_tables()

static List* schema_get_xml_visible_tables ( Oid  nspid)
static

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

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

◆ schema_to_xml()

Datum schema_to_xml ( PG_FUNCTION_ARGS  )

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

2893 {
2894  Name name = PG_GETARG_NAME(0);
2895  bool nulls = PG_GETARG_BOOL(1);
2896  bool tableforest = PG_GETARG_BOOL(2);
2897  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2898 
2899  char *schemaname;
2900  Oid nspid;
2901 
2902  schemaname = NameStr(*name);
2903  nspid = LookupExplicitNamespace(schemaname, false);
2904 
2906  nulls, tableforest, targetns, true)));
2907 }
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2849
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:603
#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:609
#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 2996 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().

2997 {
2998  Name name = PG_GETARG_NAME(0);
2999  bool nulls = PG_GETARG_BOOL(1);
3000  bool tableforest = PG_GETARG_BOOL(2);
3001  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3002  char *schemaname;
3003  Oid nspid;
3004  StringInfo xmlschema;
3005 
3006  schemaname = NameStr(*name);
3007  nspid = LookupExplicitNamespace(schemaname, false);
3008 
3009  xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3010  tableforest, targetns);
3011 
3013  xmlschema->data, nulls,
3014  tableforest, targetns, true)));
3015 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2938
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2849
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:603
#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:609
#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 2849 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().

2851 {
2852  StringInfo result;
2853  char *xmlsn;
2854  List *relid_list;
2855  ListCell *cell;
2856 
2858  true, false);
2859  result = makeStringInfo();
2860 
2861  xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
2862  appendStringInfoChar(result, '\n');
2863 
2864  if (xmlschema)
2865  appendStringInfo(result, "%s\n\n", xmlschema);
2866 
2867  SPI_connect();
2868 
2869  relid_list = schema_get_xml_visible_tables(nspid);
2870 
2871  foreach(cell, relid_list)
2872  {
2873  Oid relid = lfirst_oid(cell);
2874  StringInfo subres;
2875 
2876  subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
2877  targetns, false);
2878 
2879  appendBinaryStringInfo(result, subres->data, subres->len);
2880  appendStringInfoChar(result, '\n');
2881  }
2882 
2883  SPI_finish();
2884 
2885  xmldata_root_element_end(result, xmlsn);
2886 
2887  return result;
2888 }
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2639
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2487
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
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:2038
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2540
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2666
Definition: pg_list.h:50
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ schema_to_xmlschema()

Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

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

2984 {
2985  Name name = PG_GETARG_NAME(0);
2986  bool nulls = PG_GETARG_BOOL(1);
2987  bool tableforest = PG_GETARG_BOOL(2);
2988  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2989 
2991  nulls, tableforest, targetns)));
2992 }
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:2938
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Definition: c.h:603
#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:609
#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 2938 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().

2940 {
2941  Oid nspid;
2942  List *relid_list;
2943  List *tupdesc_list;
2944  ListCell *cell;
2945  StringInfo result;
2946 
2947  result = makeStringInfo();
2948 
2949  nspid = LookupExplicitNamespace(schemaname, false);
2950 
2951  xsd_schema_element_start(result, targetns);
2952 
2953  SPI_connect();
2954 
2955  relid_list = schema_get_xml_visible_tables(nspid);
2956 
2957  tupdesc_list = NIL;
2958  foreach(cell, relid_list)
2959  {
2960  Relation rel;
2961 
2962  rel = table_open(lfirst_oid(cell), AccessShareLock);
2963  tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
2964  table_close(rel, NoLock);
2965  }
2966 
2967  appendStringInfoString(result,
2968  map_sql_typecoll_to_xmlschema_types(tupdesc_list));
2969 
2970  appendStringInfoString(result,
2971  map_sql_schema_to_xmlschema_types(nspid, relid_list,
2972  nulls, tableforest, targetns));
2973 
2974  xsd_schema_element_end(result);
2975 
2976  SPI_finish();
2977 
2978  return result;
2979 }
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:2914
#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:2487
int SPI_connect(void)
Definition: spi.c:89
int SPI_finish(void)
Definition: spi.c:176
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:321
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3524
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:2931
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:3289
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 3754 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_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().

3757 {
3758  int i;
3759  char *xmltn;
3760 
3761  if (tablename)
3762  xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3763  else
3764  {
3765  if (tableforest)
3766  xmltn = "row";
3767  else
3768  xmltn = "table";
3769  }
3770 
3771  if (tableforest)
3772  xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
3773  else
3774  appendStringInfoString(result, "<row>\n");
3775 
3776  for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
3777  {
3778  char *colname;
3779  Datum colval;
3780  bool isnull;
3781 
3783  true, false);
3784  colval = SPI_getbinval(SPI_tuptable->vals[rownum],
3786  i,
3787  &isnull);
3788  if (isnull)
3789  {
3790  if (nulls)
3791  appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
3792  }
3793  else
3794  appendStringInfo(result, " <%s>%s</%s>\n",
3795  colname,
3797  SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
3798  colname);
3799  }
3800 
3801  if (tableforest)
3802  {
3803  xmldata_root_element_end(result, xmltn);
3804  appendStringInfoChar(result, '\n');
3805  }
3806  else
3807  appendStringInfoString(result, "</row>\n\n");
3808 }
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:2639
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:78
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:163
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2038
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
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:2666
int i
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2154

◆ stringinfo_to_xmltype()

◆ table_to_xml()

Datum table_to_xml ( PG_FUNCTION_ARGS  )

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

2558 {
2559  Oid relid = PG_GETARG_OID(0);
2560  bool nulls = PG_GETARG_BOOL(1);
2561  bool tableforest = PG_GETARG_BOOL(2);
2562  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2563 
2565  nulls, tableforest,
2566  targetns, true)));
2567 }
#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:2540
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 2792 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().

2793 {
2794  Oid relid = PG_GETARG_OID(0);
2795  bool nulls = PG_GETARG_BOOL(1);
2796  bool tableforest = PG_GETARG_BOOL(2);
2797  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2798  Relation rel;
2799  const char *xmlschema;
2800 
2801  rel = table_open(relid, AccessShareLock);
2802  xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2803  tableforest, targetns);
2804  table_close(rel, NoLock);
2805 
2807  xmlschema, nulls, tableforest,
2808  targetns, true)));
2809 }
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:3184
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:2540
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 2540 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().

2543 {
2544  StringInfoData query;
2545 
2546  initStringInfo(&query);
2547  appendStringInfo(&query, "SELECT * FROM %s",
2549  ObjectIdGetDatum(relid))));
2550  return query_to_xml_internal(query.data, get_rel_name(relid),
2551  xmlschema, nulls, tableforest,
2552  targetns, top_level);
2553 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:616
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define DatumGetCString(X)
Definition: postgres.h:566
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2673
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 2718 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().

2719 {
2720  Oid relid = PG_GETARG_OID(0);
2721  bool nulls = PG_GETARG_BOOL(1);
2722  bool tableforest = PG_GETARG_BOOL(2);
2723  const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2724  const char *result;
2725  Relation rel;
2726 
2727  rel = table_open(relid, AccessShareLock);
2728  result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
2729  tableforest, targetns);
2730  table_close(rel, NoLock);
2731 
2733 }
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:3184
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:549
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 2094 of file xml.c.

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

Referenced by map_xml_name_to_sql_identifier().

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

◆ 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:996
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:549

◆ 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_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:359
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1574
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int GetDatabaseEncoding(void)
Definition: mbutils.c:996
#define PG_CATCH()
Definition: elog.h:310
#define PG_RE_THROW()
Definition: elog.h:331
Definition: c.h:549
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317

◆ xml_is_well_formed()

Datum xml_is_well_formed ( PG_FUNCTION_ARGS  )

Definition at line 4286 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and xmloption.

4287 {
4288 #ifdef USE_LIBXML
4289  text *data = PG_GETARG_TEXT_PP(0);
4290 
4291  PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4292 #else
4293  NO_XML_SUPPORT();
4294  return 0;
4295 #endif /* not USE_LIBXML */
4296 }
#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:549

◆ xml_is_well_formed_content()

Datum xml_is_well_formed_content ( PG_FUNCTION_ARGS  )

Definition at line 4312 of file xml.c.

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

4313 {
4314 #ifdef USE_LIBXML
4315  text *data = PG_GETARG_TEXT_PP(0);
4316 
4317  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4318 #else
4319  NO_XML_SUPPORT();
4320  return 0;
4321 #endif /* not USE_LIBXML */
4322 }
#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:549

◆ xml_is_well_formed_document()

Datum xml_is_well_formed_document ( PG_FUNCTION_ARGS  )

Definition at line 4299 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.

4300 {
4301 #ifdef USE_LIBXML
4302  text *data = PG_GETARG_TEXT_PP(0);
4303 
4304  PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4305 #else
4306  NO_XML_SUPPORT();
4307  return 0;
4308 #endif /* not USE_LIBXML */
4309 }
#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:549

◆ 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:549

◆ 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:1031
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define WARNING
Definition: elog.h:40
char * text_to_cstring(const text *t)
Definition: varlena.c:204
Definition: c.h:549

◆ 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:555
StringInfoData * StringInfo
Definition: stringinfo.h:43
#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:1031
static char * buf
Definition: pg_test_fsync.c:68
#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:924
int xmloption
Definition: xml.c:98
Definition: c.h:549
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:553

◆ 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:1031
static char * buf
Definition: pg_test_fsync.c:68
#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:549

◆ 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:570
#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:4194
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
#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:46
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:784
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
int i
void * arg
Definition: c.h:549

◆ 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:555
#define DatumGetXmlP(X)
Definition: xml.h:50
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#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:549
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

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

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

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

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

◆ 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:524
#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:68
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
List * lappend(List *list, void *datum)
Definition: list.c:321
List * named_args
Definition: primnodes.h:1169
List * args
Definition: primnodes.h:1171
#define PG_CATCH()
Definition: elog.h:310
#define lfirst(lc)
Definition: pg_list.h:190
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define PG_RE_THROW()
Definition: elog.h:331
e
Definition: preproc-init.c:82
int i
void * arg
Definition: c.h:549
#define PG_TRY()
Definition: elog.h:301
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2154
Definition: pg_list.h:50
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:317
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

◆ xmlexists()

Datum xmlexists ( PG_FUNCTION_ARGS  )

Definition at line 4213 of file xml.c.

References NO_XML_SUPPORT, PG_GETARG_TEXT_PP, PG_GETARG_XML_P, and PG_RETURN_BOOL.

4214 {
4215 #ifdef USE_LIBXML
4216  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4217  xmltype *data = PG_GETARG_XML_P(1);
4218  int res_nitems;
4219 
4220  xpath_internal(xpath_expr_text, data, NULL,
4221  &res_nitems, NULL);
4222 
4223  PG_RETURN_BOOL(res_nitems > 0);
4224 #else
4225  NO_XML_SUPPORT();
4226  return 0;
4227 #endif
4228 }
#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:549

◆ 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:996
Definition: c.h:549

◆ 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:570
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
int errdetail(const char *fmt,...)
Definition: elog.c:860
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:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:784
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:447
Definition: c.h:549

◆ 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:555
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:549

◆ XmlTableDestroyOpaque()

static void XmlTableDestroyOpaque ( struct TableFuncScanState state)
static

Definition at line 4759 of file xml.c.

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

4760 {
4761 #ifdef USE_LIBXML
4762  XmlTableBuilderData *xtCxt;
4763 
4764  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
4765 
4766  /* Propagate context related error context to libxml2 */
4767  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4768 
4769  if (xtCxt->xpathscomp != NULL)
4770  {
4771  int i;
4772 
4773  for (i = 0; i < xtCxt->natts; i++)
4774  if (xtCxt->xpathscomp[i] != NULL)
4775  xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
4776  }
4777 
4778  if (xtCxt->xpathobj != NULL)
4779  xmlXPathFreeObject(xtCxt->xpathobj);
4780  if (xtCxt->xpathcomp != NULL)
4781  xmlXPathFreeCompExpr(xtCxt->xpathcomp);
4782  if (xtCxt->xpathcxt != NULL)
4783  xmlXPathFreeContext(xtCxt->xpathcxt);
4784  if (xtCxt->doc != NULL)
4785  xmlFreeDoc(xtCxt->doc);
4786  if (xtCxt->ctxt != NULL)
4787  xmlFreeParserCtxt(xtCxt->ctxt);
4788 
4789  pg_xml_done(xtCxt->xmlerrcxt, true);
4790 
4791  /* not valid anymore */
4792  xtCxt->magic = 0;
4793  state->opaque = NULL;
4794 
4795 #else
4796  NO_XML_SUPPORT();
4797 #endif /* not USE_LIBXML */
4798 }
#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 4553 of file xml.c.

References ERROR, NO_XML_SUPPORT, and xml_ereport().

4554 {
4555 #ifdef USE_LIBXML
4556  XmlTableBuilderData *xtCxt;
4557 
4558  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4559 
4560  /*
4561  * XmlTable returns table - set of composite values. The error context, is
4562  * used for producement more values, between two calls, there can be
4563  * created and used another libxml2 error context. It is libxml2 global
4564  * value, so it should be refreshed any time before any libxml2 usage,
4565  * that is finished by returning some value.
4566  */
4567  xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler);
4568 
4569  if (xtCxt->xpathobj == NULL)
4570  {
4571  xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4572  if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4573  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4574  "could not create XPath object");
4575 
4576  xtCxt->row_count = 0;
4577  }
4578 
4579  if (xtCxt->xpathobj->type == XPATH_NODESET)
4580  {
4581  if (xtCxt->xpathobj->nodesetval != NULL)
4582  {
4583  if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4584  return true;
4585  }
4586  }
4587 
4588  return false;
4589 #else
4590  NO_XML_SUPPORT();
4591  return false;
4592 #endif /* not USE_LIBXML */
4593 }
#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 4604 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_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, generate_unaccent_rules::str, TableFuncScanState::typioparams, and xml_ereport().

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

4362 {
4363 #ifdef USE_LIBXML
4364  volatile xmlParserCtxtPtr ctxt = NULL;
4365  XmlTableBuilderData *xtCxt;
4366  PgXmlErrorContext *xmlerrcxt;
4367 
4368  xtCxt = palloc0(sizeof(XmlTableBuilderData));
4369  xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4370  xtCxt->natts = natts;
4371  xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4372 
4373  xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
4374 
4375  PG_TRY();
4376  {
4377  xmlInitParser();
4378 
4379  ctxt = xmlNewParserCtxt();
4380  if (ctxt == NULL || xmlerrcxt->err_occurred)
4381  xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4382  "could not allocate parser context");
4383  }
4384  PG_CATCH();
4385  {
4386  if (ctxt != NULL)
4387  xmlFreeParserCtxt(ctxt);
4388 
4389  pg_xml_done(xmlerrcxt, true);
4390 
4391  PG_RE_THROW();
4392  }
4393  PG_END_TRY();
4394 
4395  xtCxt->xmlerrcxt = xmlerrcxt;
4396  xtCxt->ctxt = ctxt;
4397 
4398  state->opaque = xtCxt;
4399 #else
4400  NO_XML_SUPPORT();
4401 #endif /* not USE_LIBXML */
4402 }
#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:955
#define PG_CATCH()
Definition: elog.h:310
#define PG_RE_THROW()
Definition: elog.h:331
#define PG_TRY()
Definition: elog.h:301
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
#define PG_END_TRY()
Definition: elog.h:317
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 4521 of file xml.c.

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

4522 {
4523 #ifdef USE_LIBXML
4524  XmlTableBuilderData *xtCxt;
4525  xmlChar *xstr;
4526 
4527  AssertArg(PointerIsValid(path));
4528 
4529  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4530 
4531  if (*path == '\0')
4532  ereport(ERROR,
4533  (errcode(ERRCODE_DATA_EXCEPTION),
4534  errmsg("column path filter must not be empty string")));
4535 
4536  xstr = pg_xmlCharStrndup(path, strlen(path));
4537 
4538  xtCxt->xpathscomp[colnum] = xmlXPathCompile(xstr);
4539  if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4540  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4541  "invalid XPath expression");
4542 #else
4543  NO_XML_SUPPORT();
4544 #endif /* not USE_LIBXML */
4545 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define AssertArg(condition)
Definition: c.h:734
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define PointerIsValid(pointer)
Definition: c.h:626
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 4409 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().

4410 {
4411 #ifdef USE_LIBXML
4412  XmlTableBuilderData *xtCxt;
4413  xmltype *xmlval = DatumGetXmlP(value);
4414  char *str;
4415  xmlChar *xstr;
4416  int length;
4417  volatile xmlDocPtr doc = NULL;
4418  volatile xmlXPathContextPtr xpathcxt = NULL;
4419 
4420  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4421 
4422  /*
4423  * Use out function for casting to string (remove encoding property). See
4424  * comment in xml_out.
4425  */
4426  str = xml_out_internal(xmlval, 0);
4427 
4428  length = strlen(str);
4429  xstr = pg_xmlCharStrndup(str, length);
4430 
4431  PG_TRY();
4432  {
4433  doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4434  if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4435  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4436  "could not parse XML document");
4437  xpathcxt = xmlXPathNewContext(doc);
4438  if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4439  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4440  "could not allocate XPath context");
4441  xpathcxt->node = (xmlNodePtr) doc;
4442  }
4443  PG_CATCH();
4444  {
4445  if (xpathcxt != NULL)
4446  xmlXPathFreeContext(xpathcxt);
4447  if (doc != NULL)
4448  xmlFreeDoc(doc);
4449 
4450  PG_RE_THROW();
4451  }
4452  PG_END_TRY();
4453 
4454  xtCxt->doc = doc;
4455  xtCxt->xpathcxt = xpathcxt;
4456 #else
4457  NO_XML_SUPPORT();
4458 #endif /* not USE_LIBXML */
4459 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
static struct @144 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:310
#define PG_RE_THROW()
Definition: elog.h:331
Definition: c.h:549
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
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 4466 of file xml.c.

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

4467 {
4468 #ifdef USE_LIBXML
4469  XmlTableBuilderData *xtCxt;
4470 
4471  if (name == NULL)
4472  ereport(ERROR,
4473  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4474  errmsg("DEFAULT namespace is not supported")));
4475  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4476 
4477  if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4478  pg_xmlCharStrndup(name, strlen(name)),
4479  pg_xmlCharStrndup(uri, strlen(uri))))
4480  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4481  "could not set XML namespace");
4482 #else
4483  NO_XML_SUPPORT();
4484 #endif /* not USE_LIBXML */
4485 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:784
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 4492 of file xml.c.

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

4493 {
4494 #ifdef USE_LIBXML
4495  XmlTableBuilderData *xtCxt;
4496  xmlChar *xstr;
4497 
4498  xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4499 
4500  if (*path == '\0')
4501  ereport(ERROR,
4502  (errcode(ERRCODE_DATA_EXCEPTION),
4503  errmsg("row path filter must not be empty string")));
4504 
4505  xstr = pg_xmlCharStrndup(path, strlen(path));
4506 
4507  xtCxt->xpathcomp = xmlXPathCompile(xstr);
4508  if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4509  xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4510  "invalid XPath expression");
4511 #else
4512  NO_XML_SUPPORT();
4513 #endif /* not USE_LIBXML */
4514 }
#define NO_XML_SUPPORT()
Definition: xml.c:219
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
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:549

◆ 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:570
#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:784
Definition: c.h:549

◆ 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:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

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

4191 {
4192 #ifdef USE_LIBXML
4193  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4194  xmltype *data = PG_GETARG_XML_P(1);
4195  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4196  ArrayBuildState *astate;
4197 
4198  astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4199  xpath_internal(xpath_expr_text, data, namespaces,
4200  NULL, astate);
4202 #else
4203  NO_XML_SUPPORT();
4204  return 0;
4205 #endif
4206 }
#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:549

◆ xpath_exists()

Datum xpath_exists ( PG_FUNCTION_ARGS  )

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

4237 {
4238 #ifdef USE_LIBXML
4239  text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4240  xmltype *data = PG_GETARG_XML_P(1);
4241  ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4242  int res_nitems;
4243 
4244  xpath_internal(xpath_expr_text, data, namespaces,
4245  &res_nitems, NULL);
4246 
4247  PG_RETURN_BOOL(res_nitems > 0);
4248 #else
4249  NO_XML_SUPPORT();
4250  return 0;
4251 #endif
4252 }
#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:549

◆ xsd_schema_element_end()

static void xsd_schema_element_end ( StringInfo  result)
static

Definition at line 2931 of file xml.c.

References appendStringInfoString().

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

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

◆ xsd_schema_element_start()

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

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

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

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:4361
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4553
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4466
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4409
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4521
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4604
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4492
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:4759

Definition at line 207 of file xml.c.

Referenced by ExecInitTableFuncScan().