PostgreSQL Source Code git master
xml.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "catalog/namespace.h"
#include "catalog/pg_class.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "executor/spi.h"
#include "executor/tablefunc.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "nodes/miscnodes.h"
#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xml.h"
Include dependency graph for xml.c:

Go to the source code of this file.

Macros

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

Functions

static void xmldata_root_element_start (StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
 
static void xmldata_root_element_end (StringInfo result, const char *eltname)
 
static StringInfo query_to_xml_internal (const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static const char * map_sql_table_to_xmlschema (TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_schema_to_xmlschema_types (Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_catalog_to_xmlschema_types (List *nspid_list, bool nulls, bool tableforest, const char *targetns)
 
static const char * map_sql_type_to_xml_name (Oid typeoid, int typmod)
 
static const char * map_sql_typecoll_to_xmlschema_types (List *tupdesc_list)
 
static const char * map_sql_type_to_xmlschema_type (Oid typeoid, int typmod)
 
static void SPI_sql_row_to_xmlelement (uint64 rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
static void XmlTableInitOpaque (struct TableFuncScanState *state, int natts)
 
static void XmlTableSetDocument (struct TableFuncScanState *state, Datum value)
 
static void XmlTableSetNamespace (struct TableFuncScanState *state, const char *name, const char *uri)
 
static void XmlTableSetRowFilter (struct TableFuncScanState *state, const char *path)
 
static void XmlTableSetColumnFilter (struct TableFuncScanState *state, const char *path, int colnum)
 
static bool XmlTableFetchRow (struct TableFuncScanState *state)
 
static Datum XmlTableGetValue (struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
 
static void XmlTableDestroyOpaque (struct TableFuncScanState *state)
 
Datum xml_in (PG_FUNCTION_ARGS)
 
static char * xml_out_internal (xmltype *x, pg_enc target_encoding)
 
Datum xml_out (PG_FUNCTION_ARGS)
 
Datum xml_recv (PG_FUNCTION_ARGS)
 
Datum xml_send (PG_FUNCTION_ARGS)
 
static xmltypestringinfo_to_xmltype (StringInfo buf)
 
static xmltypecstring_to_xmltype (const char *string)
 
Datum xmlcomment (PG_FUNCTION_ARGS)
 
Datum xmltext (PG_FUNCTION_ARGS)
 
xmltypexmlconcat (List *args)
 
Datum xmlconcat2 (PG_FUNCTION_ARGS)
 
Datum texttoxml (PG_FUNCTION_ARGS)
 
Datum xmltotext (PG_FUNCTION_ARGS)
 
textxmltotext_with_options (xmltype *data, XmlOptionType xmloption_arg, bool indent)
 
xmltypexmlelement (XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
 
xmltypexmlparse (text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
 
xmltypexmlpi (const char *target, text *arg, bool arg_is_null, bool *result_is_null)
 
xmltypexmlroot (xmltype *data, text *version, int standalone)
 
Datum xmlvalidate (PG_FUNCTION_ARGS)
 
bool xml_is_document (xmltype *arg)
 
char * map_sql_identifier_to_xml_name (const char *ident, bool fully_escaped, bool escape_period)
 
char * map_xml_name_to_sql_identifier (const char *name)
 
char * map_sql_value_to_xml_value (Datum value, Oid type, bool xml_escape_strings)
 
char * escape_xml (const char *str)
 
static char * _SPI_strdup (const char *s)
 
static Listquery_to_oid_list (const char *query)
 
static Listschema_get_xml_visible_tables (Oid nspid)
 
static Listdatabase_get_xml_visible_schemas (void)
 
static Listdatabase_get_xml_visible_tables (void)
 
static StringInfo table_to_xml_internal (Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum table_to_xml (PG_FUNCTION_ARGS)
 
Datum query_to_xml (PG_FUNCTION_ARGS)
 
Datum cursor_to_xml (PG_FUNCTION_ARGS)
 
Datum table_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum cursor_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum table_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
Datum query_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo schema_to_xml_internal (Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
 
Datum schema_to_xml (PG_FUNCTION_ARGS)
 
static void xsd_schema_element_start (StringInfo result, const char *targetns)
 
static void xsd_schema_element_end (StringInfo result)
 
static StringInfo schema_to_xmlschema_internal (const char *schemaname, bool nulls, bool tableforest, const char *targetns)
 
Datum schema_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum schema_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xml_internal (const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xml (PG_FUNCTION_ARGS)
 
static StringInfo database_to_xmlschema_internal (bool nulls, bool tableforest, const char *targetns)
 
Datum database_to_xmlschema (PG_FUNCTION_ARGS)
 
Datum database_to_xml_and_xmlschema (PG_FUNCTION_ARGS)
 
static char * map_multipart_sql_identifier_to_xml_name (const char *a, const char *b, const char *c, const char *d)
 
Datum xpath (PG_FUNCTION_ARGS)
 
Datum xmlexists (PG_FUNCTION_ARGS)
 
Datum xpath_exists (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed_document (PG_FUNCTION_ARGS)
 
Datum xml_is_well_formed_content (PG_FUNCTION_ARGS)
 

Variables

int xmlbinary = XMLBINARY_BASE64
 
int xmloption = XMLOPTION_CONTENT
 
const TableFuncRoutine XmlTableRoutine
 

Macro Definition Documentation

◆ NAMESPACE_SQLXML

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

Definition at line 245 of file xml.c.

◆ NAMESPACE_XSD

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

Definition at line 243 of file xml.c.

◆ NAMESPACE_XSI

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

Definition at line 244 of file xml.c.

◆ NO_XML_SUPPORT

#define NO_XML_SUPPORT ( )
Value:
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
errmsg("unsupported XML feature"), \
errdetail("This functionality requires the server to be built with libxml support.")))
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

Definition at line 235 of file xml.c.

◆ PG_XML_DEFAULT_VERSION

#define PG_XML_DEFAULT_VERSION   "1.0"

Definition at line 301 of file xml.c.

◆ XML_VISIBLE_SCHEMAS

#define XML_VISIBLE_SCHEMAS   "SELECT oid FROM pg_catalog.pg_namespace WHERE pg_catalog.has_schema_privilege (oid, 'USAGE') AND NOT " XML_VISIBLE_SCHEMAS_EXCLUDE

Definition at line 2836 of file xml.c.

◆ XML_VISIBLE_SCHEMAS_EXCLUDE

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

Definition at line 2834 of file xml.c.

Function Documentation

◆ _SPI_strdup()

static char * _SPI_strdup ( const char *  s)
static

Definition at line 2727 of file xml.c.

2728{
2729 size_t len = strlen(s) + 1;
2730 char *ret = SPI_palloc(len);
2731
2732 memcpy(ret, s, len);
2733 return ret;
2734}
const void size_t len
void * SPI_palloc(Size size)
Definition: spi.c:1339

References len, and SPI_palloc().

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

◆ cstring_to_xmltype()

static xmltype * cstring_to_xmltype ( const char *  string)
static

Definition at line 474 of file xml.c.

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

References cstring_to_text().

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

◆ cursor_to_xml()

Datum cursor_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2911 of file xml.c.

2912{
2914 int32 count = PG_GETARG_INT32(1);
2915 bool nulls = PG_GETARG_BOOL(2);
2916 bool tableforest = PG_GETARG_BOOL(3);
2917 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2918
2919 StringInfoData result;
2920 Portal portal;
2921 uint64 i;
2922
2923 initStringInfo(&result);
2924
2925 if (!tableforest)
2926 {
2927 xmldata_root_element_start(&result, "table", NULL, targetns, true);
2928 appendStringInfoChar(&result, '\n');
2929 }
2930
2931 SPI_connect();
2932 portal = SPI_cursor_find(name);
2933 if (portal == NULL)
2934 ereport(ERROR,
2935 (errcode(ERRCODE_UNDEFINED_CURSOR),
2936 errmsg("cursor \"%s\" does not exist", name)));
2937
2938 SPI_cursor_fetch(portal, true, count);
2939 for (i = 0; i < SPI_processed; i++)
2940 SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2941 tableforest, targetns, true);
2942
2943 SPI_finish();
2944
2945 if (!tableforest)
2946 xmldata_root_element_end(&result, "table");
2947
2949}
int32_t int32
Definition: c.h:498
uint64_t uint64
Definition: c.h:503
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
int i
Definition: isn.c:74
uint64 SPI_processed
Definition: spi.c:44
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1796
int SPI_connect(void)
Definition: spi.c:95
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1808
int SPI_finish(void)
Definition: spi.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
char * text_to_cstring(const text *t)
Definition: varlena.c:225
const char * name
static void xmldata_root_element_start(StringInfo result, const char *eltname, const char *xmlschema, const char *targetns, bool top_level)
Definition: xml.c:2965
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:2992
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:467
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:4084
#define PG_RETURN_XML_P(x)
Definition: xml.h:63

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

◆ cursor_to_xmlschema()

Datum cursor_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3092 of file xml.c.

3093{
3095 bool nulls = PG_GETARG_BOOL(1);
3096 bool tableforest = PG_GETARG_BOOL(2);
3097 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3098 const char *xmlschema;
3099 Portal portal;
3100
3101 SPI_connect();
3102 portal = SPI_cursor_find(name);
3103 if (portal == NULL)
3104 ereport(ERROR,
3105 (errcode(ERRCODE_UNDEFINED_CURSOR),
3106 errmsg("cursor \"%s\" does not exist", name)));
3107 if (portal->tupDesc == NULL)
3108 ereport(ERROR,
3109 (errcode(ERRCODE_INVALID_CURSOR_STATE),
3110 errmsg("portal \"%s\" does not return tuples", name)));
3111
3113 InvalidOid, nulls,
3114 tableforest, targetns));
3115 SPI_finish();
3116
3118}
#define InvalidOid
Definition: postgres_ext.h:37
TupleDesc tupDesc
Definition: portal.h:160
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:474
static char * _SPI_strdup(const char *s)
Definition: xml.c:2727
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3514

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

◆ database_get_xml_visible_schemas()

static List * database_get_xml_visible_schemas ( void  )
static

Definition at line 2840 of file xml.c.

2841{
2842 return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2843}
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2836
static List * query_to_oid_list(const char *query)
Definition: xml.c:2784

References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().

◆ database_get_xml_visible_tables()

static List * database_get_xml_visible_tables ( void  )
static

Definition at line 2847 of file xml.c.

2848{
2849 /* At the moment there is no order required here. */
2850 return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2851 " WHERE relkind IN ("
2852 CppAsString2(RELKIND_RELATION) ","
2853 CppAsString2(RELKIND_MATVIEW) ","
2854 CppAsString2(RELKIND_VIEW) ")"
2855 " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2856 " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2857}
#define CppAsString2(x)
Definition: c.h:363

References CppAsString2, query_to_oid_list(), and XML_VISIBLE_SCHEMAS.

Referenced by database_to_xmlschema_internal().

◆ database_to_xml()

Datum database_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 3397 of file xml.c.

3398{
3399 bool nulls = PG_GETARG_BOOL(0);
3400 bool tableforest = PG_GETARG_BOOL(1);
3401 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3402
3404 tableforest, targetns)));
3405}
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3354

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

◆ database_to_xml_and_xmlschema()

Datum database_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3464 of file xml.c.

3465{
3466 bool nulls = PG_GETARG_BOOL(0);
3467 bool tableforest = PG_GETARG_BOOL(1);
3468 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3469 StringInfo xmlschema;
3470
3471 xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3472
3474 nulls, tableforest, targetns)));
3475}
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3409

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

◆ database_to_xml_internal()

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

Definition at line 3354 of file xml.c.

3356{
3357 StringInfo result;
3358 List *nspid_list;
3359 ListCell *cell;
3360 char *xmlcn;
3361
3363 true, false);
3364 result = makeStringInfo();
3365
3366 xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
3367 appendStringInfoChar(result, '\n');
3368
3369 if (xmlschema)
3370 appendStringInfo(result, "%s\n\n", xmlschema);
3371
3372 SPI_connect();
3373
3374 nspid_list = database_get_xml_visible_schemas();
3375
3376 foreach(cell, nspid_list)
3377 {
3378 Oid nspid = lfirst_oid(cell);
3379 StringInfo subres;
3380
3381 subres = schema_to_xml_internal(nspid, NULL, nulls,
3382 tableforest, targetns, false);
3383
3384 appendBinaryStringInfo(result, subres->data, subres->len);
3385 appendStringInfoChar(result, '\n');
3386 }
3387
3388 SPI_finish();
3389
3390 xmldata_root_element_end(result, xmlcn);
3391
3392 return result;
3393}
int nspid
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3188
Oid MyDatabaseId
Definition: globals.c:93
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:32
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
Definition: pg_list.h:54
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2378
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2840
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3179

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), StringInfoData::data, database_get_xml_visible_schemas(), get_database_name(), StringInfoData::len, lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), MyDatabaseId, nspid, schema_to_xml_internal(), SPI_connect(), SPI_finish(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by database_to_xml(), and database_to_xml_and_xmlschema().

◆ database_to_xmlschema()

Datum database_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3452 of file xml.c.

3453{
3454 bool nulls = PG_GETARG_BOOL(0);
3455 bool tableforest = PG_GETARG_BOOL(1);
3456 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3457
3459 tableforest, targetns)));
3460}

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

◆ database_to_xmlschema_internal()

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

Definition at line 3409 of file xml.c.

3411{
3412 List *relid_list;
3413 List *nspid_list;
3414 List *tupdesc_list;
3415 ListCell *cell;
3416 StringInfo result;
3417
3418 result = makeStringInfo();
3419
3420 xsd_schema_element_start(result, targetns);
3421
3422 SPI_connect();
3423
3424 relid_list = database_get_xml_visible_tables();
3425 nspid_list = database_get_xml_visible_schemas();
3426
3427 tupdesc_list = NIL;
3428 foreach(cell, relid_list)
3429 {
3430 Relation rel;
3431
3433 tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3434 table_close(rel, NoLock);
3435 }
3436
3439
3441 map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3442
3443 xsd_schema_element_end(result);
3444
3445 SPI_finish();
3446
3447 return result;
3448}
List * lappend(List *list, void *datum)
Definition: list.c:339
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
#define NIL
Definition: pg_list.h:68
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
TupleDesc rd_att
Definition: rel.h:112
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:234
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3692
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:3244
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2847
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3854
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:3261

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

Referenced by database_to_xml_and_xmlschema(), and database_to_xmlschema().

◆ escape_xml()

char * escape_xml ( const char *  str)

Definition at line 2695 of file xml.c.

2696{
2698 const char *p;
2699
2701 for (p = str; *p; p++)
2702 {
2703 switch (*p)
2704 {
2705 case '&':
2706 appendStringInfoString(&buf, "&amp;");
2707 break;
2708 case '<':
2709 appendStringInfoString(&buf, "&lt;");
2710 break;
2711 case '>':
2712 appendStringInfoString(&buf, "&gt;");
2713 break;
2714 case '\r':
2715 appendStringInfoString(&buf, "&#x0d;");
2716 break;
2717 default:
2719 break;
2720 }
2721 }
2722 return buf.data;
2723}
const char * str
static char * buf
Definition: pg_test_fsync.c:72
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:231

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

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

◆ map_multipart_sql_identifier_to_xml_name()

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

Definition at line 3483 of file xml.c.

3484{
3485 StringInfoData result;
3486
3487 initStringInfo(&result);
3488
3489 if (a)
3490 appendStringInfoString(&result,
3491 map_sql_identifier_to_xml_name(a, true, true));
3492 if (b)
3493 appendStringInfo(&result, ".%s",
3494 map_sql_identifier_to_xml_name(b, true, true));
3495 if (c)
3496 appendStringInfo(&result, ".%s",
3497 map_sql_identifier_to_xml_name(c, true, true));
3498 if (d)
3499 appendStringInfo(&result, ".%s",
3500 map_sql_identifier_to_xml_name(d, true, true));
3501
3502 return result.data;
3503}
int b
Definition: isn.c:71
int a
Definition: isn.c:70
char * c

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

Referenced by map_sql_catalog_to_xmlschema_types(), map_sql_schema_to_xmlschema_types(), map_sql_table_to_xmlschema(), and map_sql_type_to_xml_name().

◆ map_sql_catalog_to_xmlschema_types()

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

Definition at line 3692 of file xml.c.

3694{
3695 char *dbname;
3696 char *xmlcn;
3697 char *catalogtypename;
3698 StringInfoData result;
3699 ListCell *cell;
3700
3702
3703 initStringInfo(&result);
3704
3705 xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3706
3707 catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3708 dbname,
3709 NULL,
3710 NULL);
3711
3712 appendStringInfo(&result,
3713 "<xsd:complexType name=\"%s\">\n", catalogtypename);
3714 appendStringInfoString(&result,
3715 " <xsd:all>\n");
3716
3717 foreach(cell, nspid_list)
3718 {
3719 Oid nspid = lfirst_oid(cell);
3720 char *nspname = get_namespace_name(nspid);
3721 char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3722 char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3723 dbname,
3724 nspname,
3725 NULL);
3726
3727 appendStringInfo(&result,
3728 " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3729 xmlsn, schematypename);
3730 }
3731
3732 appendStringInfoString(&result,
3733 " </xsd:all>\n");
3734 appendStringInfoString(&result,
3735 "</xsd:complexType>\n\n");
3736
3737 appendStringInfo(&result,
3738 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3739 xmlcn, catalogtypename);
3740
3741 return result.data;
3742}
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3449
char * dbname
Definition: streamutil.c:49
static char * map_multipart_sql_identifier_to_xml_name(const char *a, const char *b, const char *c, const char *d)
Definition: xml.c:3483

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

Referenced by database_to_xmlschema_internal().

◆ map_sql_identifier_to_xml_name()

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

Definition at line 2378 of file xml.c.

2380{
2381#ifdef USE_LIBXML
2383 const char *p;
2384
2385 /*
2386 * SQL/XML doesn't make use of this case anywhere, so it's probably a
2387 * mistake.
2388 */
2389 Assert(fully_escaped || !escape_period);
2390
2392
2393 for (p = ident; *p; p += pg_mblen(p))
2394 {
2395 if (*p == ':' && (p == ident || fully_escaped))
2396 appendStringInfoString(&buf, "_x003A_");
2397 else if (*p == '_' && *(p + 1) == 'x')
2398 appendStringInfoString(&buf, "_x005F_");
2399 else if (fully_escaped && p == ident &&
2400 pg_strncasecmp(p, "xml", 3) == 0)
2401 {
2402 if (*p == 'x')
2403 appendStringInfoString(&buf, "_x0078_");
2404 else
2405 appendStringInfoString(&buf, "_x0058_");
2406 }
2407 else if (escape_period && *p == '.')
2408 appendStringInfoString(&buf, "_x002E_");
2409 else
2410 {
2411 pg_wchar u = sqlchar_to_unicode(p);
2412
2413 if ((p == ident)
2414 ? !is_valid_xml_namefirst(u)
2415 : !is_valid_xml_namechar(u))
2416 appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
2417 else
2419 }
2420 }
2421
2422 return buf.data;
2423#else /* not USE_LIBXML */
2425 return NULL;
2426#endif /* not USE_LIBXML */
2427}
Assert(PointerIsAligned(start, uint64))
#define ident
Definition: indent_codes.h:47
unsigned int pg_wchar
Definition: mbprint.c:31
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define NO_XML_SUPPORT()
Definition: xml.c:235

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert(), buf, ident, initStringInfo(), NO_XML_SUPPORT, pg_mblen(), and pg_strncasecmp().

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

◆ map_sql_schema_to_xmlschema_types()

static const char * map_sql_schema_to_xmlschema_types ( Oid  nspid,
List relid_list,
bool  nulls,
bool  tableforest,
const char *  targetns 
)
static

Definition at line 3619 of file xml.c.

3621{
3622 char *dbname;
3623 char *nspname;
3624 char *xmlsn;
3625 char *schematypename;
3626 StringInfoData result;
3627 ListCell *cell;
3628
3630 nspname = get_namespace_name(nspid);
3631
3632 initStringInfo(&result);
3633
3634 xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3635
3636 schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3637 dbname,
3638 nspname,
3639 NULL);
3640
3641 appendStringInfo(&result,
3642 "<xsd:complexType name=\"%s\">\n", schematypename);
3643 if (!tableforest)
3644 appendStringInfoString(&result,
3645 " <xsd:all>\n");
3646 else
3647 appendStringInfoString(&result,
3648 " <xsd:sequence>\n");
3649
3650 foreach(cell, relid_list)
3651 {
3652 Oid relid = lfirst_oid(cell);
3653 char *relname = get_rel_name(relid);
3654 char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3655 char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3656 dbname,
3657 nspname,
3658 relname);
3659
3660 if (!tableforest)
3661 appendStringInfo(&result,
3662 " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3663 xmltn, tabletypename);
3664 else
3665 appendStringInfo(&result,
3666 " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3667 xmltn, tabletypename);
3668 }
3669
3670 if (!tableforest)
3671 appendStringInfoString(&result,
3672 " </xsd:all>\n");
3673 else
3674 appendStringInfoString(&result,
3675 " </xsd:sequence>\n");
3676 appendStringInfoString(&result,
3677 "</xsd:complexType>\n\n");
3678
3679 appendStringInfo(&result,
3680 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3681 xmlsn, schematypename);
3682
3683 return result.data;
3684}
char * get_rel_name(Oid relid)
Definition: lsyscache.c:2011
NameData relname
Definition: pg_class.h:38

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

Referenced by schema_to_xmlschema_internal().

◆ map_sql_table_to_xmlschema()

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

Definition at line 3514 of file xml.c.

3516{
3517 int i;
3518 char *xmltn;
3519 char *tabletypename;
3520 char *rowtypename;
3521 StringInfoData result;
3522
3523 initStringInfo(&result);
3524
3525 if (OidIsValid(relid))
3526 {
3527 HeapTuple tuple;
3528 Form_pg_class reltuple;
3529
3530 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3531 if (!HeapTupleIsValid(tuple))
3532 elog(ERROR, "cache lookup failed for relation %u", relid);
3533 reltuple = (Form_pg_class) GETSTRUCT(tuple);
3534
3535 xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3536 true, false);
3537
3538 tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3540 get_namespace_name(reltuple->relnamespace),
3541 NameStr(reltuple->relname));
3542
3543 rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3545 get_namespace_name(reltuple->relnamespace),
3546 NameStr(reltuple->relname));
3547
3548 ReleaseSysCache(tuple);
3549 }
3550 else
3551 {
3552 if (tableforest)
3553 xmltn = "row";
3554 else
3555 xmltn = "table";
3556
3557 tabletypename = "TableType";
3558 rowtypename = "RowType";
3559 }
3560
3561 xsd_schema_element_start(&result, targetns);
3562
3563 appendStringInfoString(&result,
3565
3566 appendStringInfo(&result,
3567 "<xsd:complexType name=\"%s\">\n"
3568 " <xsd:sequence>\n",
3569 rowtypename);
3570
3571 for (i = 0; i < tupdesc->natts; i++)
3572 {
3573 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3574
3575 if (att->attisdropped)
3576 continue;
3577 appendStringInfo(&result,
3578 " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3580 true, false),
3581 map_sql_type_to_xml_name(att->atttypid, -1),
3582 nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3583 }
3584
3585 appendStringInfoString(&result,
3586 " </xsd:sequence>\n"
3587 "</xsd:complexType>\n\n");
3588
3589 if (!tableforest)
3590 {
3591 appendStringInfo(&result,
3592 "<xsd:complexType name=\"%s\">\n"
3593 " <xsd:sequence>\n"
3594 " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3595 " </xsd:sequence>\n"
3596 "</xsd:complexType>\n\n",
3597 tabletypename, rowtypename);
3598
3599 appendStringInfo(&result,
3600 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3601 xmltn, tabletypename);
3602 }
3603 else
3604 appendStringInfo(&result,
3605 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3606 xmltn, rowtypename);
3607
3608 xsd_schema_element_end(&result);
3609
3610 return result.data;
3611}
#define NameStr(name)
Definition: c.h:717
#define OidIsValid(objectId)
Definition: c.h:746
#define elog(elevel,...)
Definition: elog.h:225
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
FormData_pg_class * Form_pg_class
Definition: pg_class.h:156
#define list_make1(x1)
Definition: pg_list.h:212
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3749

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

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

◆ map_sql_type_to_xml_name()

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

Definition at line 3749 of file xml.c.

3750{
3751 StringInfoData result;
3752
3753 initStringInfo(&result);
3754
3755 switch (typeoid)
3756 {
3757 case BPCHAROID:
3758 if (typmod == -1)
3759 appendStringInfoString(&result, "CHAR");
3760 else
3761 appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3762 break;
3763 case VARCHAROID:
3764 if (typmod == -1)
3765 appendStringInfoString(&result, "VARCHAR");
3766 else
3767 appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3768 break;
3769 case NUMERICOID:
3770 if (typmod == -1)
3771 appendStringInfoString(&result, "NUMERIC");
3772 else
3773 appendStringInfo(&result, "NUMERIC_%d_%d",
3774 ((typmod - VARHDRSZ) >> 16) & 0xffff,
3775 (typmod - VARHDRSZ) & 0xffff);
3776 break;
3777 case INT4OID:
3778 appendStringInfoString(&result, "INTEGER");
3779 break;
3780 case INT2OID:
3781 appendStringInfoString(&result, "SMALLINT");
3782 break;
3783 case INT8OID:
3784 appendStringInfoString(&result, "BIGINT");
3785 break;
3786 case FLOAT4OID:
3787 appendStringInfoString(&result, "REAL");
3788 break;
3789 case FLOAT8OID:
3790 appendStringInfoString(&result, "DOUBLE");
3791 break;
3792 case BOOLOID:
3793 appendStringInfoString(&result, "BOOLEAN");
3794 break;
3795 case TIMEOID:
3796 if (typmod == -1)
3797 appendStringInfoString(&result, "TIME");
3798 else
3799 appendStringInfo(&result, "TIME_%d", typmod);
3800 break;
3801 case TIMETZOID:
3802 if (typmod == -1)
3803 appendStringInfoString(&result, "TIME_WTZ");
3804 else
3805 appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3806 break;
3807 case TIMESTAMPOID:
3808 if (typmod == -1)
3809 appendStringInfoString(&result, "TIMESTAMP");
3810 else
3811 appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3812 break;
3813 case TIMESTAMPTZOID:
3814 if (typmod == -1)
3815 appendStringInfoString(&result, "TIMESTAMP_WTZ");
3816 else
3817 appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3818 break;
3819 case DATEOID:
3820 appendStringInfoString(&result, "DATE");
3821 break;
3822 case XMLOID:
3823 appendStringInfoString(&result, "XML");
3824 break;
3825 default:
3826 {
3827 HeapTuple tuple;
3828 Form_pg_type typtuple;
3829
3830 tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3831 if (!HeapTupleIsValid(tuple))
3832 elog(ERROR, "cache lookup failed for type %u", typeoid);
3833 typtuple = (Form_pg_type) GETSTRUCT(tuple);
3834
3835 appendStringInfoString(&result,
3836 map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3838 get_namespace_name(typtuple->typnamespace),
3839 NameStr(typtuple->typname)));
3840
3841 ReleaseSysCache(tuple);
3842 }
3843 }
3844
3845 return result.data;
3846}
#define VARHDRSZ
Definition: c.h:663
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261

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

Referenced by map_sql_table_to_xmlschema(), and map_sql_type_to_xmlschema_type().

◆ map_sql_type_to_xmlschema_type()

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

Definition at line 3909 of file xml.c.

3910{
3911 StringInfoData result;
3912 const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3913
3914 initStringInfo(&result);
3915
3916 if (typeoid == XMLOID)
3917 {
3918 appendStringInfoString(&result,
3919 "<xsd:complexType mixed=\"true\">\n"
3920 " <xsd:sequence>\n"
3921 " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3922 " </xsd:sequence>\n"
3923 "</xsd:complexType>\n");
3924 }
3925 else
3926 {
3927 appendStringInfo(&result,
3928 "<xsd:simpleType name=\"%s\">\n", typename);
3929
3930 switch (typeoid)
3931 {
3932 case BPCHAROID:
3933 case VARCHAROID:
3934 case TEXTOID:
3935 appendStringInfoString(&result,
3936 " <xsd:restriction base=\"xsd:string\">\n");
3937 if (typmod != -1)
3938 appendStringInfo(&result,
3939 " <xsd:maxLength value=\"%d\"/>\n",
3940 typmod - VARHDRSZ);
3941 appendStringInfoString(&result, " </xsd:restriction>\n");
3942 break;
3943
3944 case BYTEAOID:
3945 appendStringInfo(&result,
3946 " <xsd:restriction base=\"xsd:%s\">\n"
3947 " </xsd:restriction>\n",
3948 xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3949 break;
3950
3951 case NUMERICOID:
3952 if (typmod != -1)
3953 appendStringInfo(&result,
3954 " <xsd:restriction base=\"xsd:decimal\">\n"
3955 " <xsd:totalDigits value=\"%d\"/>\n"
3956 " <xsd:fractionDigits value=\"%d\"/>\n"
3957 " </xsd:restriction>\n",
3958 ((typmod - VARHDRSZ) >> 16) & 0xffff,
3959 (typmod - VARHDRSZ) & 0xffff);
3960 break;
3961
3962 case INT2OID:
3963 appendStringInfo(&result,
3964 " <xsd:restriction base=\"xsd:short\">\n"
3965 " <xsd:maxInclusive value=\"%d\"/>\n"
3966 " <xsd:minInclusive value=\"%d\"/>\n"
3967 " </xsd:restriction>\n",
3968 SHRT_MAX, SHRT_MIN);
3969 break;
3970
3971 case INT4OID:
3972 appendStringInfo(&result,
3973 " <xsd:restriction base=\"xsd:int\">\n"
3974 " <xsd:maxInclusive value=\"%d\"/>\n"
3975 " <xsd:minInclusive value=\"%d\"/>\n"
3976 " </xsd:restriction>\n",
3977 INT_MAX, INT_MIN);
3978 break;
3979
3980 case INT8OID:
3981 appendStringInfo(&result,
3982 " <xsd:restriction base=\"xsd:long\">\n"
3983 " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
3984 " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
3985 " </xsd:restriction>\n",
3987 PG_INT64_MIN);
3988 break;
3989
3990 case FLOAT4OID:
3991 appendStringInfoString(&result,
3992 " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
3993 break;
3994
3995 case FLOAT8OID:
3996 appendStringInfoString(&result,
3997 " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
3998 break;
3999
4000 case BOOLOID:
4001 appendStringInfoString(&result,
4002 " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
4003 break;
4004
4005 case TIMEOID:
4006 case TIMETZOID:
4007 {
4008 const char *tz = (typeoid == TIMETZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
4009
4010 if (typmod == -1)
4011 appendStringInfo(&result,
4012 " <xsd:restriction base=\"xsd:time\">\n"
4013 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
4014 " </xsd:restriction>\n", tz);
4015 else if (typmod == 0)
4016 appendStringInfo(&result,
4017 " <xsd:restriction base=\"xsd:time\">\n"
4018 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
4019 " </xsd:restriction>\n", tz);
4020 else
4021 appendStringInfo(&result,
4022 " <xsd:restriction base=\"xsd:time\">\n"
4023 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
4024 " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
4025 break;
4026 }
4027
4028 case TIMESTAMPOID:
4029 case TIMESTAMPTZOID:
4030 {
4031 const char *tz = (typeoid == TIMESTAMPTZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
4032
4033 if (typmod == -1)
4034 appendStringInfo(&result,
4035 " <xsd:restriction base=\"xsd:dateTime\">\n"
4036 " <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"
4037 " </xsd:restriction>\n", tz);
4038 else if (typmod == 0)
4039 appendStringInfo(&result,
4040 " <xsd:restriction base=\"xsd:dateTime\">\n"
4041 " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
4042 " </xsd:restriction>\n", tz);
4043 else
4044 appendStringInfo(&result,
4045 " <xsd:restriction base=\"xsd:dateTime\">\n"
4046 " <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"
4047 " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
4048 break;
4049 }
4050
4051 case DATEOID:
4052 appendStringInfoString(&result,
4053 " <xsd:restriction base=\"xsd:date\">\n"
4054 " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
4055 " </xsd:restriction>\n");
4056 break;
4057
4058 default:
4059 if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
4060 {
4061 Oid base_typeoid;
4062 int32 base_typmod = -1;
4063
4064 base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
4065
4066 appendStringInfo(&result,
4067 " <xsd:restriction base=\"%s\"/>\n",
4068 map_sql_type_to_xml_name(base_typeoid, base_typmod));
4069 }
4070 break;
4071 }
4072 appendStringInfoString(&result, "</xsd:simpleType>\n");
4073 }
4074
4075 return result.data;
4076}
#define INT64_FORMAT
Definition: c.h:520
#define PG_INT64_MAX
Definition: c.h:563
#define PG_INT64_MIN
Definition: c.h:562
char get_typtype(Oid typid)
Definition: lsyscache.c:2712
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2621
int xmlbinary
Definition: xml.c:109
@ XMLBINARY_BASE64
Definition: xml.h:35

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

Referenced by map_sql_typecoll_to_xmlschema_types().

◆ map_sql_typecoll_to_xmlschema_types()

static const char * map_sql_typecoll_to_xmlschema_types ( List tupdesc_list)
static

Definition at line 3854 of file xml.c.

3855{
3856 List *uniquetypes = NIL;
3857 int i;
3858 StringInfoData result;
3859 ListCell *cell0;
3860
3861 /* extract all column types used in the set of TupleDescs */
3862 foreach(cell0, tupdesc_list)
3863 {
3864 TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3865
3866 for (i = 0; i < tupdesc->natts; i++)
3867 {
3868 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3869
3870 if (att->attisdropped)
3871 continue;
3872 uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3873 }
3874 }
3875
3876 /* add base types of domains */
3877 foreach(cell0, uniquetypes)
3878 {
3879 Oid typid = lfirst_oid(cell0);
3880 Oid basetypid = getBaseType(typid);
3881
3882 if (basetypid != typid)
3883 uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3884 }
3885
3886 /* Convert to textual form */
3887 initStringInfo(&result);
3888
3889 foreach(cell0, uniquetypes)
3890 {
3891 appendStringInfo(&result, "%s\n",
3893 -1));
3894 }
3895
3896 return result.data;
3897}
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1380
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2604
#define lfirst(lc)
Definition: pg_list.h:172
struct TupleDescData * TupleDesc
Definition: tupdesc.h:139
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3909

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

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

◆ map_sql_value_to_xml_value()

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

Definition at line 2476 of file xml.c.

2477{
2479 {
2480 ArrayType *array;
2481 Oid elmtype;
2482 int16 elmlen;
2483 bool elmbyval;
2484 char elmalign;
2485 int num_elems;
2486 Datum *elem_values;
2487 bool *elem_nulls;
2489 int i;
2490
2491 array = DatumGetArrayTypeP(value);
2492 elmtype = ARR_ELEMTYPE(array);
2493 get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2494
2495 deconstruct_array(array, elmtype,
2496 elmlen, elmbyval, elmalign,
2497 &elem_values, &elem_nulls,
2498 &num_elems);
2499
2501
2502 for (i = 0; i < num_elems; i++)
2503 {
2504 if (elem_nulls[i])
2505 continue;
2506 appendStringInfoString(&buf, "<element>");
2508 map_sql_value_to_xml_value(elem_values[i],
2509 elmtype, true));
2510 appendStringInfoString(&buf, "</element>");
2511 }
2512
2513 pfree(elem_values);
2514 pfree(elem_nulls);
2515
2516 return buf.data;
2517 }
2518 else
2519 {
2520 Oid typeOut;
2521 bool isvarlena;
2522 char *str;
2523
2524 /*
2525 * Flatten domains; the special-case treatments below should apply to,
2526 * eg, domains over boolean not just boolean.
2527 */
2529
2530 /*
2531 * Special XSD formatting for some data types
2532 */
2533 switch (type)
2534 {
2535 case BOOLOID:
2536 if (DatumGetBool(value))
2537 return "true";
2538 else
2539 return "false";
2540
2541 case DATEOID:
2542 {
2543 DateADT date;
2544 struct pg_tm tm;
2545 char buf[MAXDATELEN + 1];
2546
2548 /* XSD doesn't support infinite values */
2549 if (DATE_NOT_FINITE(date))
2550 ereport(ERROR,
2551 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2552 errmsg("date out of range"),
2553 errdetail("XML does not support infinite date values.")));
2555 &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2557
2558 return pstrdup(buf);
2559 }
2560
2561 case TIMESTAMPOID:
2562 {
2564 struct pg_tm tm;
2565 fsec_t fsec;
2566 char buf[MAXDATELEN + 1];
2567
2569
2570 /* XSD doesn't support infinite values */
2572 ereport(ERROR,
2573 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2574 errmsg("timestamp out of range"),
2575 errdetail("XML does not support infinite timestamp values.")));
2576 else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2577 EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2578 else
2579 ereport(ERROR,
2580 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2581 errmsg("timestamp out of range")));
2582
2583 return pstrdup(buf);
2584 }
2585
2586 case TIMESTAMPTZOID:
2587 {
2589 struct pg_tm tm;
2590 int tz;
2591 fsec_t fsec;
2592 const char *tzn = NULL;
2593 char buf[MAXDATELEN + 1];
2594
2596
2597 /* XSD doesn't support infinite values */
2599 ereport(ERROR,
2600 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2601 errmsg("timestamp out of range"),
2602 errdetail("XML does not support infinite timestamp values.")));
2603 else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2604 EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2605 else
2606 ereport(ERROR,
2607 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2608 errmsg("timestamp out of range")));
2609
2610 return pstrdup(buf);
2611 }
2612
2613#ifdef USE_LIBXML
2614 case BYTEAOID:
2615 {
2616 bytea *bstr = DatumGetByteaPP(value);
2617 PgXmlErrorContext *xmlerrcxt;
2618 volatile xmlBufferPtr buf = NULL;
2619 volatile xmlTextWriterPtr writer = NULL;
2620 char *result;
2621
2623
2624 PG_TRY();
2625 {
2626 buf = xmlBufferCreate();
2627 if (buf == NULL || xmlerrcxt->err_occurred)
2628 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2629 "could not allocate xmlBuffer");
2630 writer = xmlNewTextWriterMemory(buf, 0);
2631 if (writer == NULL || xmlerrcxt->err_occurred)
2632 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2633 "could not allocate xmlTextWriter");
2634
2636 xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2637 0, VARSIZE_ANY_EXHDR(bstr));
2638 else
2639 xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2640 0, VARSIZE_ANY_EXHDR(bstr));
2641
2642 /* we MUST do this now to flush data out to the buffer */
2643 xmlFreeTextWriter(writer);
2644 writer = NULL;
2645
2646 result = pstrdup((const char *) xmlBufferContent(buf));
2647 }
2648 PG_CATCH();
2649 {
2650 if (writer)
2651 xmlFreeTextWriter(writer);
2652 if (buf)
2653 xmlBufferFree(buf);
2654
2655 pg_xml_done(xmlerrcxt, true);
2656
2657 PG_RE_THROW();
2658 }
2659 PG_END_TRY();
2660
2661 xmlBufferFree(buf);
2662
2663 pg_xml_done(xmlerrcxt, false);
2664
2665 return result;
2666 }
2667#endif /* USE_LIBXML */
2668
2669 }
2670
2671 /*
2672 * otherwise, just use the type's native text representation
2673 */
2674 getTypeOutputInfo(type, &typeOut, &isvarlena);
2675 str = OidOutputFunctionCall(typeOut, value);
2676
2677 /* ... exactly as-is for XML, and when escaping is not wanted */
2678 if (type == XMLOID || !xml_escape_strings)
2679 return str;
2680
2681 /* otherwise, translate special characters as needed */
2682 return escape_xml(str);
2683 }
2684}
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3631
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:321
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4458
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4343
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1909
int16_t int16
Definition: c.h:497
int64 Timestamp
Definition: timestamp.h:38
int64 TimestampTz
Definition: timestamp.h:39
int32 fsec_t
Definition: timestamp.h:41
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:169
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
#define DATE_NOT_FINITE(j)
Definition: date.h:43
int32 DateADT
Definition: date.h:23
static DateADT DatumGetDateADT(Datum X)
Definition: date.h:54
#define PG_RE_THROW()
Definition: elog.h:404
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define PG_CATCH(...)
Definition: elog.h:381
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1763
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define MAXDATELEN
Definition: datetime.h:200
static struct @165 value
static struct pg_tm tm
Definition: localtime.c:104
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2990
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2354
#define type_is_array_domain(typid)
Definition: lsyscache.h:216
char * pstrdup(const char *in)
Definition: mcxt.c:1699
void pfree(void *pointer)
Definition: mcxt.c:1524
#define USE_XSD_DATES
Definition: miscadmin.h:239
long date
Definition: pgtypes_date.h:9
int64 timestamp
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
uintptr_t Datum
Definition: postgres.h:69
Definition: pgtime.h:35
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_year
Definition: pgtime.h:41
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
const char * type
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2476
char * escape_xml(const char *str)
Definition: xml.c:2695
struct PgXmlErrorContext PgXmlErrorContext
Definition: xml.h:48
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
@ PG_XML_STRICTNESS_ALL
Definition: xml.h:44

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

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

◆ map_xml_name_to_sql_identifier()

char * map_xml_name_to_sql_identifier ( const char *  name)

Definition at line 2434 of file xml.c.

2435{
2437 const char *p;
2438
2440
2441 for (p = name; *p; p += pg_mblen(p))
2442 {
2443 if (*p == '_' && *(p + 1) == 'x'
2444 && isxdigit((unsigned char) *(p + 2))
2445 && isxdigit((unsigned char) *(p + 3))
2446 && isxdigit((unsigned char) *(p + 4))
2447 && isxdigit((unsigned char) *(p + 5))
2448 && *(p + 6) == '_')
2449 {
2450 char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
2451 unsigned int u;
2452
2453 sscanf(p + 2, "%X", &u);
2454 pg_unicode_to_server(u, (unsigned char *) cbuf);
2456 p += 6;
2457 }
2458 else
2460 }
2461
2462 return buf.data;
2463}
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:864
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329

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

Referenced by get_rule_expr().

◆ query_to_oid_list()

static List * query_to_oid_list ( const char *  query)
static

Definition at line 2784 of file xml.c.

2785{
2786 uint64 i;
2787 List *list = NIL;
2788 int spi_result;
2789
2790 spi_result = SPI_execute(query, true, 0);
2791 if (spi_result != SPI_OK_SELECT)
2792 elog(ERROR, "SPI_execute returned %s for %s",
2793 SPI_result_code_string(spi_result), query);
2794
2795 for (i = 0; i < SPI_processed; i++)
2796 {
2797 Datum oid;
2798 bool isnull;
2799
2802 1,
2803 &isnull);
2804 if (!isnull)
2806 }
2807
2808 return list;
2809}
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:247
const char * SPI_result_code_string(int code)
Definition: spi.c:1974
SPITupleTable * SPI_tuptable
Definition: spi.c:45
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:597
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1253
#define SPI_OK_SELECT
Definition: spi.h:86
TupleDesc tupdesc
Definition: spi.h:25
HeapTuple * vals
Definition: spi.h:26

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

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

◆ query_to_xml()

Datum query_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2897 of file xml.c.

2898{
2899 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2900 bool nulls = PG_GETARG_BOOL(1);
2901 bool tableforest = PG_GETARG_BOOL(2);
2902 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2903
2905 NULL, nulls, tableforest,
2906 targetns, true)));
2907}
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:2999

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

◆ query_to_xml_and_xmlschema()

Datum query_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3143 of file xml.c.

3144{
3145 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3146 bool nulls = PG_GETARG_BOOL(1);
3147 bool tableforest = PG_GETARG_BOOL(2);
3148 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3149
3150 const char *xmlschema;
3152 Portal portal;
3153
3154 SPI_connect();
3155
3156 if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3157 elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3158
3159 if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3160 elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3161
3163 InvalidOid, nulls, tableforest, targetns));
3164 SPI_cursor_close(portal);
3165 SPI_finish();
3166
3168 xmlschema, nulls, tableforest,
3169 targetns, true)));
3170}
#define plan(x)
Definition: pg_regress.c:161
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1446
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:861
void SPI_cursor_close(Portal portal)
Definition: spi.c:1864

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

◆ query_to_xml_internal()

static StringInfo query_to_xml_internal ( const char *  query,
char *  tablename,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2999 of file xml.c.

3002{
3003 StringInfo result;
3004 char *xmltn;
3005 uint64 i;
3006
3007 if (tablename)
3008 xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3009 else
3010 xmltn = "table";
3011
3012 result = makeStringInfo();
3013
3014 SPI_connect();
3015 if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
3016 ereport(ERROR,
3017 (errcode(ERRCODE_DATA_EXCEPTION),
3018 errmsg("invalid query")));
3019
3020 if (!tableforest)
3021 {
3022 xmldata_root_element_start(result, xmltn, xmlschema,
3023 targetns, top_level);
3024 appendStringInfoChar(result, '\n');
3025 }
3026
3027 if (xmlschema)
3028 appendStringInfo(result, "%s\n\n", xmlschema);
3029
3030 for (i = 0; i < SPI_processed; i++)
3031 SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
3032 tableforest, targetns, top_level);
3033
3034 if (!tableforest)
3035 xmldata_root_element_end(result, xmltn);
3036
3037 SPI_finish();
3038
3039 return result;
3040}

References appendStringInfo(), appendStringInfoChar(), ereport, errcode(), errmsg(), ERROR, i, makeStringInfo(), map_sql_identifier_to_xml_name(), SPI_connect(), SPI_execute(), SPI_finish(), SPI_OK_SELECT, SPI_processed, SPI_sql_row_to_xmlelement(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by query_to_xml(), query_to_xml_and_xmlschema(), and table_to_xml_internal().

◆ query_to_xmlschema()

Datum query_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3063 of file xml.c.

3064{
3065 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3066 bool nulls = PG_GETARG_BOOL(1);
3067 bool tableforest = PG_GETARG_BOOL(2);
3068 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3069 const char *result;
3071 Portal portal;
3072
3073 SPI_connect();
3074
3075 if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3076 elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3077
3078 if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3079 elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3080
3082 InvalidOid, nulls,
3083 tableforest, targetns));
3084 SPI_cursor_close(portal);
3085 SPI_finish();
3086
3088}

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

◆ schema_get_xml_visible_tables()

static List * schema_get_xml_visible_tables ( Oid  nspid)
static

Definition at line 2813 of file xml.c.

2814{
2815 StringInfoData query;
2816
2817 initStringInfo(&query);
2818 appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2819 " WHERE relnamespace = %u AND relkind IN ("
2820 CppAsString2(RELKIND_RELATION) ","
2821 CppAsString2(RELKIND_MATVIEW) ","
2822 CppAsString2(RELKIND_VIEW) ")"
2823 " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2824 " ORDER BY relname;", nspid);
2825
2826 return query_to_oid_list(query.data);
2827}

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

Referenced by schema_to_xml_internal(), and schema_to_xmlschema_internal().

◆ schema_to_xml()

Datum schema_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 3222 of file xml.c.

3223{
3225 bool nulls = PG_GETARG_BOOL(1);
3226 bool tableforest = PG_GETARG_BOOL(2);
3227 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3228
3229 char *schemaname;
3230 Oid nspid;
3231
3232 schemaname = NameStr(*name);
3233 nspid = LookupExplicitNamespace(schemaname, false);
3234
3236 nulls, tableforest, targetns, true)));
3237}
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3385
Definition: c.h:712

References LookupExplicitNamespace(), name, NameStr, nspid, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xml_internal(), stringinfo_to_xmltype(), and text_to_cstring().

◆ schema_to_xml_and_xmlschema()

Datum schema_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3326 of file xml.c.

3327{
3329 bool nulls = PG_GETARG_BOOL(1);
3330 bool tableforest = PG_GETARG_BOOL(2);
3331 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3332 char *schemaname;
3333 Oid nspid;
3334 StringInfo xmlschema;
3335
3336 schemaname = NameStr(*name);
3337 nspid = LookupExplicitNamespace(schemaname, false);
3338
3339 xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3340 tableforest, targetns);
3341
3343 xmlschema->data, nulls,
3344 tableforest, targetns, true)));
3345}
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3268

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

◆ schema_to_xml_internal()

static StringInfo schema_to_xml_internal ( Oid  nspid,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 3179 of file xml.c.

3181{
3182 StringInfo result;
3183 char *xmlsn;
3184 List *relid_list;
3185 ListCell *cell;
3186
3188 true, false);
3189 result = makeStringInfo();
3190
3191 xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
3192 appendStringInfoChar(result, '\n');
3193
3194 if (xmlschema)
3195 appendStringInfo(result, "%s\n\n", xmlschema);
3196
3197 SPI_connect();
3198
3200
3201 foreach(cell, relid_list)
3202 {
3203 Oid relid = lfirst_oid(cell);
3204 StringInfo subres;
3205
3206 subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
3207 targetns, false);
3208
3209 appendBinaryStringInfo(result, subres->data, subres->len);
3210 appendStringInfoChar(result, '\n');
3211 }
3212
3213 SPI_finish();
3214
3215 xmldata_root_element_end(result, xmlsn);
3216
3217 return result;
3218}
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2813
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2866

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), StringInfoData::data, get_namespace_name(), StringInfoData::len, lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), nspid, schema_get_xml_visible_tables(), SPI_connect(), SPI_finish(), table_to_xml_internal(), xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by database_to_xml_internal(), schema_to_xml(), and schema_to_xml_and_xmlschema().

◆ schema_to_xmlschema()

Datum schema_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3313 of file xml.c.

3314{
3316 bool nulls = PG_GETARG_BOOL(1);
3317 bool tableforest = PG_GETARG_BOOL(2);
3318 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3319
3321 nulls, tableforest, targetns)));
3322}

References name, NameStr, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xmlschema_internal(), stringinfo_to_xmltype(), and text_to_cstring().

◆ schema_to_xmlschema_internal()

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

Definition at line 3268 of file xml.c.

3270{
3271 Oid nspid;
3272 List *relid_list;
3273 List *tupdesc_list;
3274 ListCell *cell;
3275 StringInfo result;
3276
3277 result = makeStringInfo();
3278
3279 nspid = LookupExplicitNamespace(schemaname, false);
3280
3281 xsd_schema_element_start(result, targetns);
3282
3283 SPI_connect();
3284
3286
3287 tupdesc_list = NIL;
3288 foreach(cell, relid_list)
3289 {
3290 Relation rel;
3291
3293 tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3294 table_close(rel, NoLock);
3295 }
3296
3299
3302 nulls, tableforest, targetns));
3303
3304 xsd_schema_element_end(result);
3305
3306 SPI_finish();
3307
3308 return result;
3309}
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3619

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

Referenced by schema_to_xml_and_xmlschema(), and schema_to_xmlschema().

◆ SPI_sql_row_to_xmlelement()

static void SPI_sql_row_to_xmlelement ( uint64  rownum,
StringInfo  result,
char *  tablename,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 4084 of file xml.c.

4087{
4088 int i;
4089 char *xmltn;
4090
4091 if (tablename)
4092 xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
4093 else
4094 {
4095 if (tableforest)
4096 xmltn = "row";
4097 else
4098 xmltn = "table";
4099 }
4100
4101 if (tableforest)
4102 xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
4103 else
4104 appendStringInfoString(result, "<row>\n");
4105
4106 for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
4107 {
4108 char *colname;
4109 Datum colval;
4110 bool isnull;
4111
4113 true, false);
4114 colval = SPI_getbinval(SPI_tuptable->vals[rownum],
4116 i,
4117 &isnull);
4118 if (isnull)
4119 {
4120 if (nulls)
4121 appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
4122 }
4123 else
4124 appendStringInfo(result, " <%s>%s</%s>\n",
4125 colname,
4128 colname);
4129 }
4130
4131 if (tableforest)
4132 {
4133 xmldata_root_element_end(result, xmltn);
4134 appendStringInfoChar(result, '\n');
4135 }
4136 else
4137 appendStringInfoString(result, "</row>\n\n");
4138}
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1309
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1199

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), i, map_sql_identifier_to_xml_name(), map_sql_value_to_xml_value(), TupleDescData::natts, SPI_fname(), SPI_getbinval(), SPI_gettypeid(), SPI_tuptable, SPITupleTable::tupdesc, SPITupleTable::vals, xmldata_root_element_end(), and xmldata_root_element_start().

Referenced by cursor_to_xml(), and query_to_xml_internal().

◆ stringinfo_to_xmltype()

◆ table_to_xml()

Datum table_to_xml ( PG_FUNCTION_ARGS  )

Definition at line 2883 of file xml.c.

2884{
2885 Oid relid = PG_GETARG_OID(0);
2886 bool nulls = PG_GETARG_BOOL(1);
2887 bool tableforest = PG_GETARG_BOOL(2);
2888 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2889
2891 nulls, tableforest,
2892 targetns, true)));
2893}
#define PG_GETARG_OID(n)
Definition: fmgr.h:275

References PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), table_to_xml_internal(), and text_to_cstring().

◆ table_to_xml_and_xmlschema()

Datum table_to_xml_and_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3122 of file xml.c.

3123{
3124 Oid relid = PG_GETARG_OID(0);
3125 bool nulls = PG_GETARG_BOOL(1);
3126 bool tableforest = PG_GETARG_BOOL(2);
3127 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3128 Relation rel;
3129 const char *xmlschema;
3130
3131 rel = table_open(relid, AccessShareLock);
3132 xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3133 tableforest, targetns);
3134 table_close(rel, NoLock);
3135
3137 xmlschema, nulls, tableforest,
3138 targetns, true)));
3139}

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

◆ table_to_xml_internal()

static StringInfo table_to_xml_internal ( Oid  relid,
const char *  xmlschema,
bool  nulls,
bool  tableforest,
const char *  targetns,
bool  top_level 
)
static

Definition at line 2866 of file xml.c.

2869{
2870 StringInfoData query;
2871
2872 initStringInfo(&query);
2873 appendStringInfo(&query, "SELECT * FROM %s",
2875 ObjectIdGetDatum(relid))));
2876 return query_to_xml_internal(query.data, get_rel_name(relid),
2877 xmlschema, nulls, tableforest,
2878 targetns, top_level);
2879}
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
static char * DatumGetCString(Datum X)
Definition: postgres.h:340
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:943

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

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

◆ table_to_xmlschema()

Datum table_to_xmlschema ( PG_FUNCTION_ARGS  )

Definition at line 3044 of file xml.c.

3045{
3046 Oid relid = PG_GETARG_OID(0);
3047 bool nulls = PG_GETARG_BOOL(1);
3048 bool tableforest = PG_GETARG_BOOL(2);
3049 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3050 const char *result;
3051 Relation rel;
3052
3053 rel = table_open(relid, AccessShareLock);
3054 result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3055 tableforest, targetns);
3056 table_close(rel, NoLock);
3057
3059}

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

◆ texttoxml()

Datum texttoxml ( PG_FUNCTION_ARGS  )

Definition at line 637 of file xml.c.

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

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

◆ xml_in()

Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 273 of file xml.c.

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

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

◆ xml_is_document()

bool xml_is_document ( xmltype arg)

Definition at line 1117 of file xml.c.

1118{
1119#ifdef USE_LIBXML
1120 xmlDocPtr doc;
1121 ErrorSaveContext escontext = {T_ErrorSaveContext};
1122
1123 /*
1124 * We'll report "true" if no soft error is reported by xml_parse().
1125 */
1126 doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
1127 GetDatabaseEncoding(), NULL, NULL, (Node *) &escontext);
1128 if (doc)
1129 xmlFreeDoc(doc);
1130
1131 return !escontext.error_occurred;
1132#else /* not USE_LIBXML */
1134 return false;
1135#endif /* not USE_LIBXML */
1136}
void * arg
@ XMLOPTION_DOCUMENT
Definition: primnodes.h:1597
bool error_occurred
Definition: miscnodes.h:47
Definition: nodes.h:131

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

Referenced by ExecEvalXmlExpr().

◆ xml_is_well_formed()

Datum xml_is_well_formed ( PG_FUNCTION_ARGS  )

Definition at line 4607 of file xml.c.

4608{
4609#ifdef USE_LIBXML
4611
4612 PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4613#else
4615 return 0;
4616#endif /* not USE_LIBXML */
4617}
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

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

◆ xml_is_well_formed_content()

Datum xml_is_well_formed_content ( PG_FUNCTION_ARGS  )

Definition at line 4633 of file xml.c.

4634{
4635#ifdef USE_LIBXML
4637
4638 PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4639#else
4641 return 0;
4642#endif /* not USE_LIBXML */
4643}
@ XMLOPTION_CONTENT
Definition: primnodes.h:1598

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

◆ xml_is_well_formed_document()

Datum xml_is_well_formed_document ( PG_FUNCTION_ARGS  )

Definition at line 4620 of file xml.c.

4621{
4622#ifdef USE_LIBXML
4624
4625 PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4626#else
4628 return 0;
4629#endif /* not USE_LIBXML */
4630}

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

◆ xml_out()

Datum xml_out ( PG_FUNCTION_ARGS  )

Definition at line 356 of file xml.c.

357{
359
360 /*
361 * xml_out removes the encoding property in all cases. This is because we
362 * cannot control from here whether the datum will be converted to a
363 * different client encoding, so we'd do more harm than good by including
364 * it.
365 */
367}
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int x
Definition: isn.c:72
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:312
#define PG_GETARG_XML_P(n)
Definition: xml.h:62

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

◆ xml_out_internal()

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

Definition at line 312 of file xml.c.

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

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

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

◆ xml_recv()

Datum xml_recv ( PG_FUNCTION_ARGS  )

Definition at line 371 of file xml.c.

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

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

◆ xml_send()

Datum xml_send ( PG_FUNCTION_ARGS  )

Definition at line 438 of file xml.c.

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

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

◆ xmlcomment()

Datum xmlcomment ( PG_FUNCTION_ARGS  )

Definition at line 491 of file xml.c.

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

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

◆ xmlconcat()

xmltype * xmlconcat ( List args)

Definition at line 553 of file xml.c.

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

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

Referenced by ExecEvalXmlExpr(), and xmlconcat2().

◆ xmlconcat2()

Datum xmlconcat2 ( PG_FUNCTION_ARGS  )

Definition at line 619 of file xml.c.

620{
621 if (PG_ARGISNULL(0))
622 {
623 if (PG_ARGISNULL(1))
625 else
627 }
628 else if (PG_ARGISNULL(1))
630 else
632 PG_GETARG_XML_P(1))));
633}
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define list_make2(x1, x2)
Definition: pg_list.h:214
xmltype * xmlconcat(List *args)
Definition: xml.c:553

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

◆ xmldata_root_element_end()

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

Definition at line 2992 of file xml.c.

2993{
2994 appendStringInfo(result, "</%s>\n", eltname);
2995}

References appendStringInfo().

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

◆ xmldata_root_element_start()

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

Definition at line 2965 of file xml.c.

2968{
2969 /* This isn't really wrong but currently makes no sense. */
2970 Assert(top_level || !xmlschema);
2971
2972 appendStringInfo(result, "<%s", eltname);
2973 if (top_level)
2974 {
2975 appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
2976 if (strlen(targetns) > 0)
2977 appendStringInfo(result, " xmlns=\"%s\"", targetns);
2978 }
2979 if (xmlschema)
2980 {
2981 /* FIXME: better targets */
2982 if (strlen(targetns) > 0)
2983 appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
2984 else
2985 appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
2986 }
2987 appendStringInfoString(result, ">\n");
2988}
#define NAMESPACE_XSI
Definition: xml.c:244

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

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

◆ xmlelement()

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

Definition at line 857 of file xml.c.

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

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

Referenced by ExecEvalXmlExpr().

◆ xmlexists()

Datum xmlexists ( PG_FUNCTION_ARGS  )

Definition at line 4542 of file xml.c.

4543{
4544#ifdef USE_LIBXML
4545 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4547 int res_nitems;
4548
4549 xpath_internal(xpath_expr_text, data, NULL,
4550 &res_nitems, NULL);
4551
4552 PG_RETURN_BOOL(res_nitems > 0);
4553#else
4555 return 0;
4556#endif
4557}

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

◆ xmlparse()

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

Definition at line 981 of file xml.c.

982{
983#ifdef USE_LIBXML
984 xmlDocPtr doc;
985
986 doc = xml_parse(data, xmloption_arg, preserve_whitespace,
987 GetDatabaseEncoding(), NULL, NULL, NULL);
988 xmlFreeDoc(doc);
989
990 return (xmltype *) data;
991#else
993 return NULL;
994#endif
995}

References data, GetDatabaseEncoding(), and NO_XML_SUPPORT.

Referenced by ExecEvalXmlExpr(), and texttoxml().

◆ xmlpi()

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

Definition at line 999 of file xml.c.

1000{
1001#ifdef USE_LIBXML
1002 xmltype *result;
1004
1005 if (pg_strcasecmp(target, "xml") == 0)
1006 ereport(ERROR,
1007 (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
1008 errmsg("invalid XML processing instruction"),
1009 errdetail("XML processing instruction target name cannot be \"%s\".", target)));
1010
1011 /*
1012 * Following the SQL standard, the null check comes after the syntax check
1013 * above.
1014 */
1015 *result_is_null = arg_is_null;
1016 if (*result_is_null)
1017 return NULL;
1018
1020
1021 appendStringInfo(&buf, "<?%s", target);
1022
1023 if (arg != NULL)
1024 {
1025 char *string;
1026
1027 string = text_to_cstring(arg);
1028 if (strstr(string, "?>") != NULL)
1029 ereport(ERROR,
1030 (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
1031 errmsg("invalid XML processing instruction"),
1032 errdetail("XML processing instruction cannot contain \"?>\".")));
1033
1035 appendStringInfoString(&buf, string + strspn(string, " "));
1036 pfree(string);
1037 }
1039
1040 result = stringinfo_to_xmltype(&buf);
1041 pfree(buf.data);
1042 return result;
1043#else
1045 return NULL;
1046#endif
1047}
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char string[11]
Definition: preproc-type.c:52

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

Referenced by ExecEvalXmlExpr().

◆ xmlroot()

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

Definition at line 1051 of file xml.c.

1052{
1053#ifdef USE_LIBXML
1054 char *str;
1055 size_t len;
1056 xmlChar *orig_version;
1057 int orig_standalone;
1059
1060 len = VARSIZE(data) - VARHDRSZ;
1062
1063 parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
1064
1065 if (version)
1066 orig_version = xml_text2xmlChar(version);
1067 else
1068 orig_version = NULL;
1069
1070 switch (standalone)
1071 {
1072 case XML_STANDALONE_YES:
1073 orig_standalone = 1;
1074 break;
1075 case XML_STANDALONE_NO:
1076 orig_standalone = 0;
1077 break;
1079 orig_standalone = -1;
1080 break;
1082 /* leave original value */
1083 break;
1084 }
1085
1087 print_xml_decl(&buf, orig_version, 0, orig_standalone);
1089
1090 return stringinfo_to_xmltype(&buf);
1091#else
1093 return NULL;
1094#endif
1095}
@ XML_STANDALONE_OMITTED
Definition: xml.h:30
@ XML_STANDALONE_NO_VALUE
Definition: xml.h:29
@ XML_STANDALONE_YES
Definition: xml.h:27
@ XML_STANDALONE_NO
Definition: xml.h:28

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

Referenced by ExecEvalXmlExpr().

◆ XmlTableDestroyOpaque()

static void XmlTableDestroyOpaque ( struct TableFuncScanState state)
static

Definition at line 5077 of file xml.c.

5078{
5079#ifdef USE_LIBXML
5080 XmlTableBuilderData *xtCxt;
5081
5082 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
5083
5084 /* Propagate our own error context to libxml2 */
5085 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
5086
5087 if (xtCxt->xpathscomp != NULL)
5088 {
5089 int i;
5090
5091 for (i = 0; i < xtCxt->natts; i++)
5092 if (xtCxt->xpathscomp[i] != NULL)
5093 xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
5094 }
5095
5096 if (xtCxt->xpathobj != NULL)
5097 xmlXPathFreeObject(xtCxt->xpathobj);
5098 if (xtCxt->xpathcomp != NULL)
5099 xmlXPathFreeCompExpr(xtCxt->xpathcomp);
5100 if (xtCxt->xpathcxt != NULL)
5101 xmlXPathFreeContext(xtCxt->xpathcxt);
5102 if (xtCxt->doc != NULL)
5103 xmlFreeDoc(xtCxt->doc);
5104 if (xtCxt->ctxt != NULL)
5105 xmlFreeParserCtxt(xtCxt->ctxt);
5106
5107 pg_xml_done(xtCxt->xmlerrcxt, true);
5108
5109 /* not valid anymore */
5110 xtCxt->magic = 0;
5111 state->opaque = NULL;
5112
5113#else
5115#endif /* not USE_LIBXML */
5116}
Definition: regguts.h:323

References i, NO_XML_SUPPORT, and pg_xml_done().

◆ XmlTableFetchRow()

static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4880 of file xml.c.

4881{
4882#ifdef USE_LIBXML
4883 XmlTableBuilderData *xtCxt;
4884
4885 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4886
4887 /* Propagate our own error context to libxml2 */
4888 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
4889
4890 if (xtCxt->xpathobj == NULL)
4891 {
4892 xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4893 if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4894 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4895 "could not create XPath object");
4896
4897 xtCxt->row_count = 0;
4898 }
4899
4900 if (xtCxt->xpathobj->type == XPATH_NODESET)
4901 {
4902 if (xtCxt->xpathobj->nodesetval != NULL)
4903 {
4904 if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4905 return true;
4906 }
4907 }
4908
4909 return false;
4910#else
4912 return false;
4913#endif /* not USE_LIBXML */
4914}

References ERROR, NO_XML_SUPPORT, and xml_ereport().

◆ XmlTableGetValue()

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

Definition at line 4925 of file xml.c.

4927{
4928#ifdef USE_LIBXML
4929 Datum result = (Datum) 0;
4930 XmlTableBuilderData *xtCxt;
4931 volatile xmlXPathObjectPtr xpathobj = NULL;
4932
4933 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4934
4935 Assert(xtCxt->xpathobj &&
4936 xtCxt->xpathobj->type == XPATH_NODESET &&
4937 xtCxt->xpathobj->nodesetval != NULL);
4938
4939 /* Propagate our own error context to libxml2 */
4940 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
4941
4942 *isnull = false;
4943
4944 Assert(xtCxt->xpathscomp[colnum] != NULL);
4945
4946 PG_TRY();
4947 {
4948 xmlNodePtr cur;
4949 char *cstr = NULL;
4950
4951 /* Set current node as entry point for XPath evaluation */
4952 cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
4953 xtCxt->xpathcxt->node = cur;
4954
4955 /* Evaluate column path */
4956 xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
4957 if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4958 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4959 "could not create XPath object");
4960
4961 /*
4962 * There are four possible cases, depending on the number of nodes
4963 * returned by the XPath expression and the type of the target column:
4964 * a) XPath returns no nodes. b) The target type is XML (return all
4965 * as XML). For non-XML return types: c) One node (return content).
4966 * d) Multiple nodes (error).
4967 */
4968 if (xpathobj->type == XPATH_NODESET)
4969 {
4970 int count = 0;
4971
4972 if (xpathobj->nodesetval != NULL)
4973 count = xpathobj->nodesetval->nodeNr;
4974
4975 if (xpathobj->nodesetval == NULL || count == 0)
4976 {
4977 *isnull = true;
4978 }
4979 else
4980 {
4981 if (typid == XMLOID)
4982 {
4983 text *textstr;
4985
4986 /* Concatenate serialized values */
4988 for (int i = 0; i < count; i++)
4989 {
4990 textstr =
4991 xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
4992 xtCxt->xmlerrcxt);
4993
4994 appendStringInfoText(&str, textstr);
4995 }
4996 cstr = str.data;
4997 }
4998 else
4999 {
5000 xmlChar *str;
5001
5002 if (count > 1)
5003 ereport(ERROR,
5004 (errcode(ERRCODE_CARDINALITY_VIOLATION),
5005 errmsg("more than one value returned by column XPath expression")));
5006
5007 str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);
5008 cstr = str ? xml_pstrdup_and_free(str) : "";
5009 }
5010 }
5011 }
5012 else if (xpathobj->type == XPATH_STRING)
5013 {
5014 /* Content should be escaped when target will be XML */
5015 if (typid == XMLOID)
5016 cstr = escape_xml((char *) xpathobj->stringval);
5017 else
5018 cstr = (char *) xpathobj->stringval;
5019 }
5020 else if (xpathobj->type == XPATH_BOOLEAN)
5021 {
5022 char typcategory;
5023 bool typispreferred;
5024 xmlChar *str;
5025
5026 /* Allow implicit casting from boolean to numbers */
5027 get_type_category_preferred(typid, &typcategory, &typispreferred);
5028
5029 if (typcategory != TYPCATEGORY_NUMERIC)
5030 str = xmlXPathCastBooleanToString(xpathobj->boolval);
5031 else
5032 str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval));
5033
5034 cstr = xml_pstrdup_and_free(str);
5035 }
5036 else if (xpathobj->type == XPATH_NUMBER)
5037 {
5038 xmlChar *str;
5039
5040 str = xmlXPathCastNumberToString(xpathobj->floatval);
5041 cstr = xml_pstrdup_and_free(str);
5042 }
5043 else
5044 elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
5045
5046 /*
5047 * By here, either cstr contains the result value, or the isnull flag
5048 * has been set.
5049 */
5050 Assert(cstr || *isnull);
5051
5052 if (!*isnull)
5053 result = InputFunctionCall(&state->in_functions[colnum],
5054 cstr,
5055 state->typioparams[colnum],
5056 typmod);
5057 }
5058 PG_FINALLY();
5059 {
5060 if (xpathobj != NULL)
5061 xmlXPathFreeObject(xpathobj);
5062 }
5063 PG_END_TRY();
5064
5065 return result;
5066#else
5068 return 0;
5069#endif /* not USE_LIBXML */
5070}
struct cursor * cur
Definition: ecpg.c:29
#define PG_FINALLY(...)
Definition: elog.h:388
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1530
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2793

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

◆ XmlTableInitOpaque()

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

Definition at line 4682 of file xml.c.

4683{
4684#ifdef USE_LIBXML
4685 volatile xmlParserCtxtPtr ctxt = NULL;
4686 XmlTableBuilderData *xtCxt;
4687 PgXmlErrorContext *xmlerrcxt;
4688
4689 xtCxt = palloc0(sizeof(XmlTableBuilderData));
4690 xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4691 xtCxt->natts = natts;
4692 xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4693
4695
4696 PG_TRY();
4697 {
4698 xmlInitParser();
4699
4700 ctxt = xmlNewParserCtxt();
4701 if (ctxt == NULL || xmlerrcxt->err_occurred)
4702 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4703 "could not allocate parser context");
4704 }
4705 PG_CATCH();
4706 {
4707 if (ctxt != NULL)
4708 xmlFreeParserCtxt(ctxt);
4709
4710 pg_xml_done(xmlerrcxt, true);
4711
4712 PG_RE_THROW();
4713 }
4714 PG_END_TRY();
4715
4716 xtCxt->xmlerrcxt = xmlerrcxt;
4717 xtCxt->ctxt = ctxt;
4718
4719 state->opaque = xtCxt;
4720#else
4722#endif /* not USE_LIBXML */
4723}
void * palloc0(Size size)
Definition: mcxt.c:1347

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

◆ XmlTableSetColumnFilter()

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

Definition at line 4845 of file xml.c.

4846{
4847#ifdef USE_LIBXML
4848 XmlTableBuilderData *xtCxt;
4849 xmlChar *xstr;
4850
4851 Assert(PointerIsValid(path));
4852
4853 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4854
4855 if (*path == '\0')
4856 ereport(ERROR,
4857 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
4858 errmsg("column path filter must not be empty string")));
4859
4860 xstr = pg_xmlCharStrndup(path, strlen(path));
4861
4862 /* We require XmlTableSetDocument to have been done already */
4863 Assert(xtCxt->xpathcxt != NULL);
4864
4865 xtCxt->xpathscomp[colnum] = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
4866 if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4867 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4868 "invalid XPath expression");
4869#else
4871#endif /* not USE_LIBXML */
4872}
#define PointerIsValid(pointer)
Definition: c.h:734

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

◆ XmlTableSetDocument()

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

Definition at line 4730 of file xml.c.

4731{
4732#ifdef USE_LIBXML
4733 XmlTableBuilderData *xtCxt;
4734 xmltype *xmlval = DatumGetXmlP(value);
4735 char *str;
4736 xmlChar *xstr;
4737 int length;
4738 volatile xmlDocPtr doc = NULL;
4739 volatile xmlXPathContextPtr xpathcxt = NULL;
4740
4741 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4742
4743 /*
4744 * Use out function for casting to string (remove encoding property). See
4745 * comment in xml_out.
4746 */
4747 str = xml_out_internal(xmlval, 0);
4748
4749 length = strlen(str);
4750 xstr = pg_xmlCharStrndup(str, length);
4751
4752 PG_TRY();
4753 {
4754 doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4755 if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4756 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4757 "could not parse XML document");
4758 xpathcxt = xmlXPathNewContext(doc);
4759 if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4760 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4761 "could not allocate XPath context");
4762 xpathcxt->node = (xmlNodePtr) doc;
4763 }
4764 PG_CATCH();
4765 {
4766 if (xpathcxt != NULL)
4767 xmlXPathFreeContext(xpathcxt);
4768 if (doc != NULL)
4769 xmlFreeDoc(doc);
4770
4771 PG_RE_THROW();
4772 }
4773 PG_END_TRY();
4774
4775 xtCxt->doc = doc;
4776 xtCxt->xpathcxt = xpathcxt;
4777#else
4779#endif /* not USE_LIBXML */
4780}

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

◆ XmlTableSetNamespace()

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

Definition at line 4787 of file xml.c.

4788{
4789#ifdef USE_LIBXML
4790 XmlTableBuilderData *xtCxt;
4791
4792 if (name == NULL)
4793 ereport(ERROR,
4794 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4795 errmsg("DEFAULT namespace is not supported")));
4796 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4797
4798 if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4799 pg_xmlCharStrndup(name, strlen(name)),
4800 pg_xmlCharStrndup(uri, strlen(uri))))
4801 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4802 "could not set XML namespace");
4803#else
4805#endif /* not USE_LIBXML */
4806}

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

◆ XmlTableSetRowFilter()

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

Definition at line 4813 of file xml.c.

4814{
4815#ifdef USE_LIBXML
4816 XmlTableBuilderData *xtCxt;
4817 xmlChar *xstr;
4818
4819 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4820
4821 if (*path == '\0')
4822 ereport(ERROR,
4823 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
4824 errmsg("row path filter must not be empty string")));
4825
4826 xstr = pg_xmlCharStrndup(path, strlen(path));
4827
4828 /* We require XmlTableSetDocument to have been done already */
4829 Assert(xtCxt->xpathcxt != NULL);
4830
4831 xtCxt->xpathcomp = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
4832 if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4833 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4834 "invalid XPath expression");
4835#else
4837#endif /* not USE_LIBXML */
4838}

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

◆ xmltext()

Datum xmltext ( PG_FUNCTION_ARGS  )

Definition at line 527 of file xml.c.

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

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

◆ xmltotext()

Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 646 of file xml.c.

647{
649
650 /* It's actually binary compatible. */
652}
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372

References data, PG_GETARG_XML_P, and PG_RETURN_TEXT_P.

◆ xmltotext_with_options()

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

Definition at line 656 of file xml.c.

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

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

Referenced by ExecEvalXmlExpr().

◆ xmlvalidate()

Datum xmlvalidate ( PG_FUNCTION_ARGS  )

Definition at line 1107 of file xml.c.

1108{
1109 ereport(ERROR,
1110 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1111 errmsg("xmlvalidate is not implemented")));
1112 return 0;
1113}

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

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4519 of file xml.c.

4520{
4521#ifdef USE_LIBXML
4522 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4524 ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4525 ArrayBuildState *astate;
4526
4527 astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4528 xpath_internal(xpath_expr_text, data, namespaces,
4529 NULL, astate);
4531#else
4533 return 0;
4534#endif
4535}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5293
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5420
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143

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

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

◆ xpath_exists()

Datum xpath_exists ( PG_FUNCTION_ARGS  )

Definition at line 4565 of file xml.c.

4566{
4567#ifdef USE_LIBXML
4568 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4570 ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4571 int res_nitems;
4572
4573 xpath_internal(xpath_expr_text, data, namespaces,
4574 &res_nitems, NULL);
4575
4576 PG_RETURN_BOOL(res_nitems > 0);
4577#else
4579 return 0;
4580#endif
4581}

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

◆ xsd_schema_element_end()

static void xsd_schema_element_end ( StringInfo  result)
static

Definition at line 3261 of file xml.c.

3262{
3263 appendStringInfoString(result, "</xsd:schema>");
3264}

References appendStringInfoString().

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

◆ xsd_schema_element_start()

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

Definition at line 3244 of file xml.c.

3245{
3247 "<xsd:schema\n"
3248 " xmlns:xsd=\"" NAMESPACE_XSD "\"");
3249 if (strlen(targetns) > 0)
3250 appendStringInfo(result,
3251 "\n"
3252 " targetNamespace=\"%s\"\n"
3253 " elementFormDefault=\"qualified\"",
3254 targetns);
3256 ">\n\n");
3257}
#define NAMESPACE_XSD
Definition: xml.c:243

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

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

Variable Documentation

◆ xmlbinary

int xmlbinary = XMLBINARY_BASE64

Definition at line 109 of file xml.c.

Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().

◆ xmloption

int xmloption = XMLOPTION_CONTENT

Definition at line 110 of file xml.c.

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

◆ XmlTableRoutine

const TableFuncRoutine XmlTableRoutine
Initial value:
=
{
.InitOpaque = XmlTableInitOpaque,
.SetDocument = XmlTableSetDocument,
.SetNamespace = XmlTableSetNamespace,
.SetRowFilter = XmlTableSetRowFilter,
.SetColumnFilter = XmlTableSetColumnFilter,
.FetchRow = XmlTableFetchRow,
.GetValue = XmlTableGetValue,
.DestroyOpaque = XmlTableDestroyOpaque
}
static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts)
Definition: xml.c:4682
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4787
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4813
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4925
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4730
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:5077
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4880
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4845

Definition at line 223 of file xml.c.

Referenced by ExecInitTableFuncScan().