Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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

◆ NAMESPACE_XSD

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

Definition at line 242 of file xml.c.

◆ NAMESPACE_XSI

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

Definition at line 243 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:1207
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150

Definition at line 234 of file xml.c.

◆ PG_XML_DEFAULT_VERSION

#define PG_XML_DEFAULT_VERSION   "1.0"

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

◆ XML_VISIBLE_SCHEMAS_EXCLUDE

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

Definition at line 2874 of file xml.c.

Function Documentation

◆ _SPI_strdup()

static char * _SPI_strdup ( const char *  s)
static

Definition at line 2767 of file xml.c.

2768{
2769 size_t len = strlen(s) + 1;
2770 char *ret = SPI_palloc(len);
2771
2772 memcpy(ret, s, len);
2773 return ret;
2774}
const void size_t len
void * SPI_palloc(Size size)
Definition: spi.c:1338

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

474{
475 return (xmltype *) cstring_to_text(string);
476}
Definition: c.h:693
text * cstring_to_text(const char *s)
Definition: varlena.c:181

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

2952{
2954 int32 count = PG_GETARG_INT32(1);
2955 bool nulls = PG_GETARG_BOOL(2);
2956 bool tableforest = PG_GETARG_BOOL(3);
2957 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
2958
2959 StringInfoData result;
2960 Portal portal;
2961 uint64 i;
2962
2963 initStringInfo(&result);
2964
2965 if (!tableforest)
2966 {
2967 xmldata_root_element_start(&result, "table", NULL, targetns, true);
2968 appendStringInfoChar(&result, '\n');
2969 }
2970
2971 SPI_connect();
2972 portal = SPI_cursor_find(name);
2973 if (portal == NULL)
2974 ereport(ERROR,
2975 (errcode(ERRCODE_UNDEFINED_CURSOR),
2976 errmsg("cursor \"%s\" does not exist", name)));
2977
2978 SPI_cursor_fetch(portal, true, count);
2979 for (i = 0; i < SPI_processed; i++)
2980 SPI_sql_row_to_xmlelement(i, &result, NULL, nulls,
2981 tableforest, targetns, true);
2982
2983 SPI_finish();
2984
2985 if (!tableforest)
2986 xmldata_root_element_end(&result, "table");
2987
2989}
int32_t int32
Definition: c.h:535
uint64_t uint64
Definition: c.h:540
#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:77
uint64 SPI_processed
Definition: spi.c:44
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1794
int SPI_connect(void)
Definition: spi.c:94
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1806
int SPI_finish(void)
Definition: spi.c:182
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:214
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:3005
static void xmldata_root_element_end(StringInfo result, const char *eltname)
Definition: xml.c:3032
static xmltype * stringinfo_to_xmltype(StringInfo buf)
Definition: xml.c:466
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:4124
#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 3132 of file xml.c.

3133{
3135 bool nulls = PG_GETARG_BOOL(1);
3136 bool tableforest = PG_GETARG_BOOL(2);
3137 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3138 const char *xmlschema;
3139 Portal portal;
3140
3141 SPI_connect();
3142 portal = SPI_cursor_find(name);
3143 if (portal == NULL)
3144 ereport(ERROR,
3145 (errcode(ERRCODE_UNDEFINED_CURSOR),
3146 errmsg("cursor \"%s\" does not exist", name)));
3147 if (portal->tupDesc == NULL)
3148 ereport(ERROR,
3149 (errcode(ERRCODE_INVALID_CURSOR_STATE),
3150 errmsg("portal \"%s\" does not return tuples", name)));
3151
3153 InvalidOid, nulls,
3154 tableforest, targetns));
3155 SPI_finish();
3156
3158}
#define InvalidOid
Definition: postgres_ext.h:37
TupleDesc tupDesc
Definition: portal.h:159
static xmltype * cstring_to_xmltype(const char *string)
Definition: xml.c:473
static char * _SPI_strdup(const char *s)
Definition: xml.c:2767
static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3554

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

2881{
2882 return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;");
2883}
#define XML_VISIBLE_SCHEMAS
Definition: xml.c:2876
static List * query_to_oid_list(const char *query)
Definition: xml.c:2824

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

2888{
2889 /* At the moment there is no order required here. */
2890 return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
2891 " WHERE relkind IN ("
2892 CppAsString2(RELKIND_RELATION) ","
2893 CppAsString2(RELKIND_MATVIEW) ","
2894 CppAsString2(RELKIND_VIEW) ")"
2895 " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
2896 " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
2897}
#define CppAsString2(x)
Definition: c.h:419

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

3438{
3439 bool nulls = PG_GETARG_BOOL(0);
3440 bool tableforest = PG_GETARG_BOOL(1);
3441 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3442
3444 tableforest, targetns)));
3445}
static StringInfo database_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3394

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

3505{
3506 bool nulls = PG_GETARG_BOOL(0);
3507 bool tableforest = PG_GETARG_BOOL(1);
3508 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3509 StringInfo xmlschema;
3510
3511 xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
3512
3514 nulls, tableforest, targetns)));
3515}
static StringInfo database_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3449

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

3396{
3397 StringInfo result;
3398 List *nspid_list;
3399 ListCell *cell;
3400 char *xmlcn;
3401
3403 true, false);
3404 result = makeStringInfo();
3405
3406 xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true);
3407 appendStringInfoChar(result, '\n');
3408
3409 if (xmlschema)
3410 appendStringInfo(result, "%s\n\n", xmlschema);
3411
3412 SPI_connect();
3413
3414 nspid_list = database_get_xml_visible_schemas();
3415
3416 foreach(cell, nspid_list)
3417 {
3418 Oid nspid = lfirst_oid(cell);
3419 StringInfo subres;
3420
3421 subres = schema_to_xml_internal(nspid, NULL, nulls,
3422 tableforest, targetns, false);
3423
3424 appendBinaryStringInfo(result, subres->data, subres->len);
3425 appendStringInfoChar(result, '\n');
3426 }
3427
3428 SPI_finish();
3429
3430 xmldata_root_element_end(result, xmlcn);
3431
3432 return result;
3433}
int nspid
Oid MyDatabaseId
Definition: globals.c:94
char * get_database_name(Oid dbid)
Definition: lsyscache.c:1259
#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:2418
static List * database_get_xml_visible_schemas(void)
Definition: xml.c:2880
static StringInfo schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:3219

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

3493{
3494 bool nulls = PG_GETARG_BOOL(0);
3495 bool tableforest = PG_GETARG_BOOL(1);
3496 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
3497
3499 tableforest, targetns)));
3500}

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

3451{
3452 List *relid_list;
3453 List *nspid_list;
3454 List *tupdesc_list;
3455 ListCell *cell;
3456 StringInfo result;
3457
3458 result = makeStringInfo();
3459
3460 xsd_schema_element_start(result, targetns);
3461
3462 SPI_connect();
3463
3464 relid_list = database_get_xml_visible_tables();
3465 nspid_list = database_get_xml_visible_schemas();
3466
3467 tupdesc_list = NIL;
3468 foreach(cell, relid_list)
3469 {
3470 Relation rel;
3471
3473 tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3474 table_close(rel, NoLock);
3475 }
3476
3479
3481 map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns));
3482
3483 xsd_schema_element_end(result);
3484
3485 SPI_finish();
3486
3487 return result;
3488}
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:252
static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3732
static void xsd_schema_element_start(StringInfo result, const char *targetns)
Definition: xml.c:3284
static List * database_get_xml_visible_tables(void)
Definition: xml.c:2887
static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list)
Definition: xml.c:3894
static void xsd_schema_element_end(StringInfo result)
Definition: xml.c:3301

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

2736{
2738 const char *p;
2739
2741 for (p = str; *p; p++)
2742 {
2743 switch (*p)
2744 {
2745 case '&':
2746 appendStringInfoString(&buf, "&amp;");
2747 break;
2748 case '<':
2749 appendStringInfoString(&buf, "&lt;");
2750 break;
2751 case '>':
2752 appendStringInfoString(&buf, "&gt;");
2753 break;
2754 case '\r':
2755 appendStringInfoString(&buf, "&#x0d;");
2756 break;
2757 default:
2759 break;
2760 }
2761 }
2762 return buf.data;
2763}
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 3523 of file xml.c.

3524{
3525 StringInfoData result;
3526
3527 initStringInfo(&result);
3528
3529 if (a)
3530 appendStringInfoString(&result,
3531 map_sql_identifier_to_xml_name(a, true, true));
3532 if (b)
3533 appendStringInfo(&result, ".%s",
3534 map_sql_identifier_to_xml_name(b, true, true));
3535 if (c)
3536 appendStringInfo(&result, ".%s",
3537 map_sql_identifier_to_xml_name(c, true, true));
3538 if (d)
3539 appendStringInfo(&result, ".%s",
3540 map_sql_identifier_to_xml_name(d, true, true));
3541
3542 return result.data;
3543}
int b
Definition: isn.c:74
int a
Definition: isn.c:73
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 3732 of file xml.c.

3734{
3735 char *dbname;
3736 char *xmlcn;
3737 char *catalogtypename;
3738 StringInfoData result;
3739 ListCell *cell;
3740
3742
3743 initStringInfo(&result);
3744
3745 xmlcn = map_sql_identifier_to_xml_name(dbname, true, false);
3746
3747 catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType",
3748 dbname,
3749 NULL,
3750 NULL);
3751
3752 appendStringInfo(&result,
3753 "<xsd:complexType name=\"%s\">\n", catalogtypename);
3754 appendStringInfoString(&result,
3755 " <xsd:all>\n");
3756
3757 foreach(cell, nspid_list)
3758 {
3759 Oid nspid = lfirst_oid(cell);
3760 char *nspname = get_namespace_name(nspid);
3761 char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3762 char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3763 dbname,
3764 nspname,
3765 NULL);
3766
3767 appendStringInfo(&result,
3768 " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3769 xmlsn, schematypename);
3770 }
3771
3772 appendStringInfoString(&result,
3773 " </xsd:all>\n");
3774 appendStringInfoString(&result,
3775 "</xsd:complexType>\n\n");
3776
3777 appendStringInfo(&result,
3778 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3779 xmlcn, catalogtypename);
3780
3781 return result.data;
3782}
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3533
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:3523

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

2420{
2421#ifdef USE_LIBXML
2423 const char *p;
2424
2425 /*
2426 * SQL/XML doesn't make use of this case anywhere, so it's probably a
2427 * mistake.
2428 */
2429 Assert(fully_escaped || !escape_period);
2430
2432
2433 for (p = ident; *p; p += pg_mblen(p))
2434 {
2435 if (*p == ':' && (p == ident || fully_escaped))
2436 appendStringInfoString(&buf, "_x003A_");
2437 else if (*p == '_' && *(p + 1) == 'x')
2438 appendStringInfoString(&buf, "_x005F_");
2439 else if (fully_escaped && p == ident &&
2440 pg_strncasecmp(p, "xml", 3) == 0)
2441 {
2442 if (*p == 'x')
2443 appendStringInfoString(&buf, "_x0078_");
2444 else
2445 appendStringInfoString(&buf, "_x0058_");
2446 }
2447 else if (escape_period && *p == '.')
2448 appendStringInfoString(&buf, "_x002E_");
2449 else
2450 {
2451 pg_wchar u = sqlchar_to_unicode(p);
2452
2453 if ((p == ident)
2454 ? !is_valid_xml_namefirst(u)
2455 : !is_valid_xml_namechar(u))
2456 appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
2457 else
2459 }
2460 }
2461
2462 return buf.data;
2463#else /* not USE_LIBXML */
2465 return NULL;
2466#endif /* not USE_LIBXML */
2467}
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:1024
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define NO_XML_SUPPORT()
Definition: xml.c:234

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

3661{
3662 char *dbname;
3663 char *nspname;
3664 char *xmlsn;
3665 char *schematypename;
3666 StringInfoData result;
3667 ListCell *cell;
3668
3670 nspname = get_namespace_name(nspid);
3671
3672 initStringInfo(&result);
3673
3674 xmlsn = map_sql_identifier_to_xml_name(nspname, true, false);
3675
3676 schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType",
3677 dbname,
3678 nspname,
3679 NULL);
3680
3681 appendStringInfo(&result,
3682 "<xsd:complexType name=\"%s\">\n", schematypename);
3683 if (!tableforest)
3684 appendStringInfoString(&result,
3685 " <xsd:all>\n");
3686 else
3687 appendStringInfoString(&result,
3688 " <xsd:sequence>\n");
3689
3690 foreach(cell, relid_list)
3691 {
3692 Oid relid = lfirst_oid(cell);
3693 char *relname = get_rel_name(relid);
3694 char *xmltn = map_sql_identifier_to_xml_name(relname, true, false);
3695 char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType",
3696 dbname,
3697 nspname,
3698 relname);
3699
3700 if (!tableforest)
3701 appendStringInfo(&result,
3702 " <xsd:element name=\"%s\" type=\"%s\"/>\n",
3703 xmltn, tabletypename);
3704 else
3705 appendStringInfo(&result,
3706 " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n",
3707 xmltn, tabletypename);
3708 }
3709
3710 if (!tableforest)
3711 appendStringInfoString(&result,
3712 " </xsd:all>\n");
3713 else
3714 appendStringInfoString(&result,
3715 " </xsd:sequence>\n");
3716 appendStringInfoString(&result,
3717 "</xsd:complexType>\n\n");
3718
3719 appendStringInfo(&result,
3720 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3721 xmlsn, schematypename);
3722
3723 return result.data;
3724}
char * get_rel_name(Oid relid)
Definition: lsyscache.c:2095
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 3554 of file xml.c.

3556{
3557 int i;
3558 char *xmltn;
3559 char *tabletypename;
3560 char *rowtypename;
3561 StringInfoData result;
3562
3563 initStringInfo(&result);
3564
3565 if (OidIsValid(relid))
3566 {
3567 HeapTuple tuple;
3568 Form_pg_class reltuple;
3569
3570 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
3571 if (!HeapTupleIsValid(tuple))
3572 elog(ERROR, "cache lookup failed for relation %u", relid);
3573 reltuple = (Form_pg_class) GETSTRUCT(tuple);
3574
3575 xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname),
3576 true, false);
3577
3578 tabletypename = map_multipart_sql_identifier_to_xml_name("TableType",
3580 get_namespace_name(reltuple->relnamespace),
3581 NameStr(reltuple->relname));
3582
3583 rowtypename = map_multipart_sql_identifier_to_xml_name("RowType",
3585 get_namespace_name(reltuple->relnamespace),
3586 NameStr(reltuple->relname));
3587
3588 ReleaseSysCache(tuple);
3589 }
3590 else
3591 {
3592 if (tableforest)
3593 xmltn = "row";
3594 else
3595 xmltn = "table";
3596
3597 tabletypename = "TableType";
3598 rowtypename = "RowType";
3599 }
3600
3601 xsd_schema_element_start(&result, targetns);
3602
3603 appendStringInfoString(&result,
3605
3606 appendStringInfo(&result,
3607 "<xsd:complexType name=\"%s\">\n"
3608 " <xsd:sequence>\n",
3609 rowtypename);
3610
3611 for (i = 0; i < tupdesc->natts; i++)
3612 {
3613 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3614
3615 if (att->attisdropped)
3616 continue;
3617 appendStringInfo(&result,
3618 " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n",
3620 true, false),
3621 map_sql_type_to_xml_name(att->atttypid, -1),
3622 nulls ? " nillable=\"true\"" : " minOccurs=\"0\"");
3623 }
3624
3625 appendStringInfoString(&result,
3626 " </xsd:sequence>\n"
3627 "</xsd:complexType>\n\n");
3628
3629 if (!tableforest)
3630 {
3631 appendStringInfo(&result,
3632 "<xsd:complexType name=\"%s\">\n"
3633 " <xsd:sequence>\n"
3634 " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
3635 " </xsd:sequence>\n"
3636 "</xsd:complexType>\n\n",
3637 tabletypename, rowtypename);
3638
3639 appendStringInfo(&result,
3640 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3641 xmltn, tabletypename);
3642 }
3643 else
3644 appendStringInfo(&result,
3645 "<xsd:element name=\"%s\" type=\"%s\"/>\n\n",
3646 xmltn, rowtypename);
3647
3648 xsd_schema_element_end(&result);
3649
3650 return result.data;
3651}
#define NameStr(name)
Definition: c.h:752
#define OidIsValid(objectId)
Definition: c.h:775
#define elog(elevel,...)
Definition: elog.h:226
#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:202
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:262
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod)
Definition: xml.c:3789

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

3790{
3791 StringInfoData result;
3792
3793 initStringInfo(&result);
3794
3795 switch (typeoid)
3796 {
3797 case BPCHAROID:
3798 if (typmod == -1)
3799 appendStringInfoString(&result, "CHAR");
3800 else
3801 appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ);
3802 break;
3803 case VARCHAROID:
3804 if (typmod == -1)
3805 appendStringInfoString(&result, "VARCHAR");
3806 else
3807 appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ);
3808 break;
3809 case NUMERICOID:
3810 if (typmod == -1)
3811 appendStringInfoString(&result, "NUMERIC");
3812 else
3813 appendStringInfo(&result, "NUMERIC_%d_%d",
3814 ((typmod - VARHDRSZ) >> 16) & 0xffff,
3815 (typmod - VARHDRSZ) & 0xffff);
3816 break;
3817 case INT4OID:
3818 appendStringInfoString(&result, "INTEGER");
3819 break;
3820 case INT2OID:
3821 appendStringInfoString(&result, "SMALLINT");
3822 break;
3823 case INT8OID:
3824 appendStringInfoString(&result, "BIGINT");
3825 break;
3826 case FLOAT4OID:
3827 appendStringInfoString(&result, "REAL");
3828 break;
3829 case FLOAT8OID:
3830 appendStringInfoString(&result, "DOUBLE");
3831 break;
3832 case BOOLOID:
3833 appendStringInfoString(&result, "BOOLEAN");
3834 break;
3835 case TIMEOID:
3836 if (typmod == -1)
3837 appendStringInfoString(&result, "TIME");
3838 else
3839 appendStringInfo(&result, "TIME_%d", typmod);
3840 break;
3841 case TIMETZOID:
3842 if (typmod == -1)
3843 appendStringInfoString(&result, "TIME_WTZ");
3844 else
3845 appendStringInfo(&result, "TIME_WTZ_%d", typmod);
3846 break;
3847 case TIMESTAMPOID:
3848 if (typmod == -1)
3849 appendStringInfoString(&result, "TIMESTAMP");
3850 else
3851 appendStringInfo(&result, "TIMESTAMP_%d", typmod);
3852 break;
3853 case TIMESTAMPTZOID:
3854 if (typmod == -1)
3855 appendStringInfoString(&result, "TIMESTAMP_WTZ");
3856 else
3857 appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod);
3858 break;
3859 case DATEOID:
3860 appendStringInfoString(&result, "DATE");
3861 break;
3862 case XMLOID:
3863 appendStringInfoString(&result, "XML");
3864 break;
3865 default:
3866 {
3867 HeapTuple tuple;
3868 Form_pg_type typtuple;
3869
3870 tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid));
3871 if (!HeapTupleIsValid(tuple))
3872 elog(ERROR, "cache lookup failed for type %u", typeoid);
3873 typtuple = (Form_pg_type) GETSTRUCT(tuple);
3874
3875 appendStringInfoString(&result,
3876 map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT",
3878 get_namespace_name(typtuple->typnamespace),
3879 NameStr(typtuple->typname)));
3880
3881 ReleaseSysCache(tuple);
3882 }
3883 }
3884
3885 return result.data;
3886}
#define VARHDRSZ
Definition: c.h:698
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 3949 of file xml.c.

3950{
3951 StringInfoData result;
3952 const char *typename = map_sql_type_to_xml_name(typeoid, typmod);
3953
3954 initStringInfo(&result);
3955
3956 if (typeoid == XMLOID)
3957 {
3958 appendStringInfoString(&result,
3959 "<xsd:complexType mixed=\"true\">\n"
3960 " <xsd:sequence>\n"
3961 " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n"
3962 " </xsd:sequence>\n"
3963 "</xsd:complexType>\n");
3964 }
3965 else
3966 {
3967 appendStringInfo(&result,
3968 "<xsd:simpleType name=\"%s\">\n", typename);
3969
3970 switch (typeoid)
3971 {
3972 case BPCHAROID:
3973 case VARCHAROID:
3974 case TEXTOID:
3975 appendStringInfoString(&result,
3976 " <xsd:restriction base=\"xsd:string\">\n");
3977 if (typmod != -1)
3978 appendStringInfo(&result,
3979 " <xsd:maxLength value=\"%d\"/>\n",
3980 typmod - VARHDRSZ);
3981 appendStringInfoString(&result, " </xsd:restriction>\n");
3982 break;
3983
3984 case BYTEAOID:
3985 appendStringInfo(&result,
3986 " <xsd:restriction base=\"xsd:%s\">\n"
3987 " </xsd:restriction>\n",
3988 xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary");
3989 break;
3990
3991 case NUMERICOID:
3992 if (typmod != -1)
3993 appendStringInfo(&result,
3994 " <xsd:restriction base=\"xsd:decimal\">\n"
3995 " <xsd:totalDigits value=\"%d\"/>\n"
3996 " <xsd:fractionDigits value=\"%d\"/>\n"
3997 " </xsd:restriction>\n",
3998 ((typmod - VARHDRSZ) >> 16) & 0xffff,
3999 (typmod - VARHDRSZ) & 0xffff);
4000 break;
4001
4002 case INT2OID:
4003 appendStringInfo(&result,
4004 " <xsd:restriction base=\"xsd:short\">\n"
4005 " <xsd:maxInclusive value=\"%d\"/>\n"
4006 " <xsd:minInclusive value=\"%d\"/>\n"
4007 " </xsd:restriction>\n",
4008 SHRT_MAX, SHRT_MIN);
4009 break;
4010
4011 case INT4OID:
4012 appendStringInfo(&result,
4013 " <xsd:restriction base=\"xsd:int\">\n"
4014 " <xsd:maxInclusive value=\"%d\"/>\n"
4015 " <xsd:minInclusive value=\"%d\"/>\n"
4016 " </xsd:restriction>\n",
4017 INT_MAX, INT_MIN);
4018 break;
4019
4020 case INT8OID:
4021 appendStringInfo(&result,
4022 " <xsd:restriction base=\"xsd:long\">\n"
4023 " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n"
4024 " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n"
4025 " </xsd:restriction>\n",
4027 PG_INT64_MIN);
4028 break;
4029
4030 case FLOAT4OID:
4031 appendStringInfoString(&result,
4032 " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n");
4033 break;
4034
4035 case FLOAT8OID:
4036 appendStringInfoString(&result,
4037 " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n");
4038 break;
4039
4040 case BOOLOID:
4041 appendStringInfoString(&result,
4042 " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n");
4043 break;
4044
4045 case TIMEOID:
4046 case TIMETZOID:
4047 {
4048 const char *tz = (typeoid == TIMETZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
4049
4050 if (typmod == -1)
4051 appendStringInfo(&result,
4052 " <xsd:restriction base=\"xsd:time\">\n"
4053 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
4054 " </xsd:restriction>\n", tz);
4055 else if (typmod == 0)
4056 appendStringInfo(&result,
4057 " <xsd:restriction base=\"xsd:time\">\n"
4058 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
4059 " </xsd:restriction>\n", tz);
4060 else
4061 appendStringInfo(&result,
4062 " <xsd:restriction base=\"xsd:time\">\n"
4063 " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
4064 " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
4065 break;
4066 }
4067
4068 case TIMESTAMPOID:
4069 case TIMESTAMPTZOID:
4070 {
4071 const char *tz = (typeoid == TIMESTAMPTZOID ? "(\\+|-)\\p{Nd}{2}:\\p{Nd}{2}" : "");
4072
4073 if (typmod == -1)
4074 appendStringInfo(&result,
4075 " <xsd:restriction base=\"xsd:dateTime\">\n"
4076 " <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"
4077 " </xsd:restriction>\n", tz);
4078 else if (typmod == 0)
4079 appendStringInfo(&result,
4080 " <xsd:restriction base=\"xsd:dateTime\">\n"
4081 " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
4082 " </xsd:restriction>\n", tz);
4083 else
4084 appendStringInfo(&result,
4085 " <xsd:restriction base=\"xsd:dateTime\">\n"
4086 " <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"
4087 " </xsd:restriction>\n", typmod - VARHDRSZ, tz);
4088 break;
4089 }
4090
4091 case DATEOID:
4092 appendStringInfoString(&result,
4093 " <xsd:restriction base=\"xsd:date\">\n"
4094 " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n"
4095 " </xsd:restriction>\n");
4096 break;
4097
4098 default:
4099 if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
4100 {
4101 Oid base_typeoid;
4102 int32 base_typmod = -1;
4103
4104 base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod);
4105
4106 appendStringInfo(&result,
4107 " <xsd:restriction base=\"%s\"/>\n",
4108 map_sql_type_to_xml_name(base_typeoid, base_typmod));
4109 }
4110 break;
4111 }
4112 appendStringInfoString(&result, "</xsd:simpleType>\n");
4113 }
4114
4115 return result.data;
4116}
#define INT64_FORMAT
Definition: c.h:557
#define PG_INT64_MAX
Definition: c.h:598
#define PG_INT64_MIN
Definition: c.h:597
char get_typtype(Oid typid)
Definition: lsyscache.c:2796
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2705
int xmlbinary
Definition: xml.c:108
@ 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 3894 of file xml.c.

3895{
3896 List *uniquetypes = NIL;
3897 int i;
3898 StringInfoData result;
3899 ListCell *cell0;
3900
3901 /* extract all column types used in the set of TupleDescs */
3902 foreach(cell0, tupdesc_list)
3903 {
3904 TupleDesc tupdesc = (TupleDesc) lfirst(cell0);
3905
3906 for (i = 0; i < tupdesc->natts; i++)
3907 {
3908 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
3909
3910 if (att->attisdropped)
3911 continue;
3912 uniquetypes = list_append_unique_oid(uniquetypes, att->atttypid);
3913 }
3914 }
3915
3916 /* add base types of domains */
3917 foreach(cell0, uniquetypes)
3918 {
3919 Oid typid = lfirst_oid(cell0);
3920 Oid basetypid = getBaseType(typid);
3921
3922 if (basetypid != typid)
3923 uniquetypes = list_append_unique_oid(uniquetypes, basetypid);
3924 }
3925
3926 /* Convert to textual form */
3927 initStringInfo(&result);
3928
3929 foreach(cell0, uniquetypes)
3930 {
3931 appendStringInfo(&result, "%s\n",
3933 -1));
3934 }
3935
3936 return result.data;
3937}
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1380
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2688
#define lfirst(lc)
Definition: pg_list.h:172
struct TupleDescData * TupleDesc
Definition: tupdesc.h:145
static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
Definition: xml.c:3949

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

2517{
2519 {
2520 ArrayType *array;
2521 Oid elmtype;
2522 int16 elmlen;
2523 bool elmbyval;
2524 char elmalign;
2525 int num_elems;
2526 Datum *elem_values;
2527 bool *elem_nulls;
2529 int i;
2530
2531 array = DatumGetArrayTypeP(value);
2532 elmtype = ARR_ELEMTYPE(array);
2533 get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
2534
2535 deconstruct_array(array, elmtype,
2536 elmlen, elmbyval, elmalign,
2537 &elem_values, &elem_nulls,
2538 &num_elems);
2539
2541
2542 for (i = 0; i < num_elems; i++)
2543 {
2544 if (elem_nulls[i])
2545 continue;
2546 appendStringInfoString(&buf, "<element>");
2548 map_sql_value_to_xml_value(elem_values[i],
2549 elmtype, true));
2550 appendStringInfoString(&buf, "</element>");
2551 }
2552
2553 pfree(elem_values);
2554 pfree(elem_nulls);
2555
2556 return buf.data;
2557 }
2558 else
2559 {
2560 Oid typeOut;
2561 bool isvarlena;
2562 char *str;
2563
2564 /*
2565 * Flatten domains; the special-case treatments below should apply to,
2566 * eg, domains over boolean not just boolean.
2567 */
2569
2570 /*
2571 * Special XSD formatting for some data types
2572 */
2573 switch (type)
2574 {
2575 case BOOLOID:
2576 if (DatumGetBool(value))
2577 return "true";
2578 else
2579 return "false";
2580
2581 case DATEOID:
2582 {
2583 DateADT date;
2584 struct pg_tm tm;
2585 char buf[MAXDATELEN + 1];
2586
2588 /* XSD doesn't support infinite values */
2589 if (DATE_NOT_FINITE(date))
2590 ereport(ERROR,
2591 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2592 errmsg("date out of range"),
2593 errdetail("XML does not support infinite date values.")));
2595 &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
2597
2598 return pstrdup(buf);
2599 }
2600
2601 case TIMESTAMPOID:
2602 {
2604 struct pg_tm tm;
2605 fsec_t fsec;
2606 char buf[MAXDATELEN + 1];
2607
2609
2610 /* XSD doesn't support infinite values */
2612 ereport(ERROR,
2613 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2614 errmsg("timestamp out of range"),
2615 errdetail("XML does not support infinite timestamp values.")));
2616 else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
2617 EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
2618 else
2619 ereport(ERROR,
2620 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2621 errmsg("timestamp out of range")));
2622
2623 return pstrdup(buf);
2624 }
2625
2626 case TIMESTAMPTZOID:
2627 {
2629 struct pg_tm tm;
2630 int tz;
2631 fsec_t fsec;
2632 const char *tzn = NULL;
2633 char buf[MAXDATELEN + 1];
2634
2636
2637 /* XSD doesn't support infinite values */
2639 ereport(ERROR,
2640 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2641 errmsg("timestamp out of range"),
2642 errdetail("XML does not support infinite timestamp values.")));
2643 else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
2644 EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
2645 else
2646 ereport(ERROR,
2647 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2648 errmsg("timestamp out of range")));
2649
2650 return pstrdup(buf);
2651 }
2652
2653#ifdef USE_LIBXML
2654 case BYTEAOID:
2655 {
2656 bytea *bstr = DatumGetByteaPP(value);
2657 PgXmlErrorContext *xmlerrcxt;
2658 volatile xmlBufferPtr buf = NULL;
2659 volatile xmlTextWriterPtr writer = NULL;
2660 char *result;
2661
2663
2664 PG_TRY();
2665 {
2666 buf = xmlBufferCreate();
2667 if (buf == NULL || xmlerrcxt->err_occurred)
2668 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2669 "could not allocate xmlBuffer");
2670 writer = xmlNewTextWriterMemory(buf, 0);
2671 if (writer == NULL || xmlerrcxt->err_occurred)
2672 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
2673 "could not allocate xmlTextWriter");
2674
2676 xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
2677 0, VARSIZE_ANY_EXHDR(bstr));
2678 else
2679 xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
2680 0, VARSIZE_ANY_EXHDR(bstr));
2681
2682 /* we MUST do this now to flush data out to the buffer */
2683 xmlFreeTextWriter(writer);
2684 writer = NULL;
2685
2686 result = pstrdup((const char *) xmlBufferContent(buf));
2687 }
2688 PG_CATCH();
2689 {
2690 if (writer)
2691 xmlFreeTextWriter(writer);
2692 if (buf)
2693 xmlBufferFree(buf);
2694
2695 pg_xml_done(xmlerrcxt, true);
2696
2697 PG_RE_THROW();
2698 }
2699 PG_END_TRY();
2700
2701 xmlBufferFree(buf);
2702
2703 pg_xml_done(xmlerrcxt, false);
2704
2705 return result;
2706 }
2707#endif /* USE_LIBXML */
2708
2709 }
2710
2711 /*
2712 * otherwise, just use the type's native text representation
2713 */
2714 getTypeOutputInfo(type, &typeOut, &isvarlena);
2715 str = OidOutputFunctionCall(typeOut, value);
2716
2717 /* ... exactly as-is for XML, and when escaping is not wanted */
2718 if (type == XMLOID || !xml_escape_strings)
2719 return str;
2720
2721 /* otherwise, translate special characters as needed */
2722 return escape_xml(str);
2723 }
2724}
#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:4464
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4349
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1910
int16_t int16
Definition: c.h:534
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:405
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define PG_CATCH(...)
Definition: elog.h:382
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1762
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define MAXDATELEN
Definition: datetime.h:200
static struct @166 value
static struct pg_tm tm
Definition: localtime.c:104
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:3074
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2438
#define type_is_array_domain(typid)
Definition: lsyscache.h:216
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void pfree(void *pointer)
Definition: mcxt.c:1594
#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:100
uint64_t Datum
Definition: postgres.h:70
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
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition: varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition: varatt.h:486
const char * type
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2516
char * escape_xml(const char *str)
Definition: xml.c:2735
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 2474 of file xml.c.

2475{
2477 const char *p;
2478
2480
2481 for (p = name; *p; p += pg_mblen(p))
2482 {
2483 if (*p == '_' && *(p + 1) == 'x'
2484 && isxdigit((unsigned char) *(p + 2))
2485 && isxdigit((unsigned char) *(p + 3))
2486 && isxdigit((unsigned char) *(p + 4))
2487 && isxdigit((unsigned char) *(p + 5))
2488 && *(p + 6) == '_')
2489 {
2490 char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
2491 unsigned int u;
2492
2493 sscanf(p + 2, "%X", &u);
2494 pg_unicode_to_server(u, (unsigned char *) cbuf);
2496 p += 6;
2497 }
2498 else
2500 }
2501
2502 return buf.data;
2503}
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:865
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329

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

Referenced by get_rule_expr().

◆ query_to_oid_list()

static List * query_to_oid_list ( const char *  query)
static

Definition at line 2824 of file xml.c.

2825{
2826 uint64 i;
2827 List *list = NIL;
2828 int spi_result;
2829
2830 spi_result = SPI_execute(query, true, 0);
2831 if (spi_result != SPI_OK_SELECT)
2832 elog(ERROR, "SPI_execute returned %s for %s",
2833 SPI_result_code_string(spi_result), query);
2834
2835 for (i = 0; i < SPI_processed; i++)
2836 {
2837 Datum oid;
2838 bool isnull;
2839
2842 1,
2843 &isnull);
2844 if (!isnull)
2846 }
2847
2848 return list;
2849}
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:252
const char * SPI_result_code_string(int code)
Definition: spi.c:1972
SPITupleTable * SPI_tuptable
Definition: spi.c:45
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:596
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
Definition: spi.c:1252
#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 2937 of file xml.c.

2938{
2939 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
2940 bool nulls = PG_GETARG_BOOL(1);
2941 bool tableforest = PG_GETARG_BOOL(2);
2942 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2943
2945 NULL, nulls, tableforest,
2946 targetns, true)));
2947}
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:3039

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

3184{
3185 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3186 bool nulls = PG_GETARG_BOOL(1);
3187 bool tableforest = PG_GETARG_BOOL(2);
3188 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3189
3190 const char *xmlschema;
3192 Portal portal;
3193
3194 SPI_connect();
3195
3196 if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3197 elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3198
3199 if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3200 elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3201
3203 InvalidOid, nulls, tableforest, targetns));
3204 SPI_cursor_close(portal);
3205 SPI_finish();
3206
3208 xmlschema, nulls, tableforest,
3209 targetns, true)));
3210}
#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:1445
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:860
void SPI_cursor_close(Portal portal)
Definition: spi.c:1862

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

3042{
3043 StringInfo result;
3044 char *xmltn;
3045 uint64 i;
3046
3047 if (tablename)
3048 xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
3049 else
3050 xmltn = "table";
3051
3052 result = makeStringInfo();
3053
3054 SPI_connect();
3055 if (SPI_execute(query, true, 0) != SPI_OK_SELECT)
3056 ereport(ERROR,
3057 (errcode(ERRCODE_DATA_EXCEPTION),
3058 errmsg("invalid query")));
3059
3060 if (!tableforest)
3061 {
3062 xmldata_root_element_start(result, xmltn, xmlschema,
3063 targetns, top_level);
3064 appendStringInfoChar(result, '\n');
3065 }
3066
3067 if (xmlschema)
3068 appendStringInfo(result, "%s\n\n", xmlschema);
3069
3070 for (i = 0; i < SPI_processed; i++)
3071 SPI_sql_row_to_xmlelement(i, result, tablename, nulls,
3072 tableforest, targetns, top_level);
3073
3074 if (!tableforest)
3075 xmldata_root_element_end(result, xmltn);
3076
3077 SPI_finish();
3078
3079 return result;
3080}

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

3104{
3105 char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
3106 bool nulls = PG_GETARG_BOOL(1);
3107 bool tableforest = PG_GETARG_BOOL(2);
3108 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3109 const char *result;
3111 Portal portal;
3112
3113 SPI_connect();
3114
3115 if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
3116 elog(ERROR, "SPI_prepare(\"%s\") failed", query);
3117
3118 if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
3119 elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
3120
3122 InvalidOid, nulls,
3123 tableforest, targetns));
3124 SPI_cursor_close(portal);
3125 SPI_finish();
3126
3128}

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

2854{
2855 StringInfoData query;
2856
2857 initStringInfo(&query);
2858 appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
2859 " WHERE relnamespace = %u AND relkind IN ("
2860 CppAsString2(RELKIND_RELATION) ","
2861 CppAsString2(RELKIND_MATVIEW) ","
2862 CppAsString2(RELKIND_VIEW) ")"
2863 " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
2864 " ORDER BY relname;", nspid);
2865
2866 return query_to_oid_list(query.data);
2867}

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

3263{
3265 bool nulls = PG_GETARG_BOOL(1);
3266 bool tableforest = PG_GETARG_BOOL(2);
3267 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3268
3269 char *schemaname;
3270 Oid nspid;
3271
3272 schemaname = NameStr(*name);
3273 nspid = LookupExplicitNamespace(schemaname, false);
3274
3276 nulls, tableforest, targetns, true)));
3277}
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3455
Definition: c.h:747

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

3367{
3369 bool nulls = PG_GETARG_BOOL(1);
3370 bool tableforest = PG_GETARG_BOOL(2);
3371 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3372 char *schemaname;
3373 Oid nspid;
3374 StringInfo xmlschema;
3375
3376 schemaname = NameStr(*name);
3377 nspid = LookupExplicitNamespace(schemaname, false);
3378
3379 xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
3380 tableforest, targetns);
3381
3383 xmlschema->data, nulls,
3384 tableforest, targetns, true)));
3385}
static StringInfo schema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3308

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

3221{
3222 StringInfo result;
3223 char *xmlsn;
3224 List *relid_list;
3225 ListCell *cell;
3226
3228 true, false);
3229 result = makeStringInfo();
3230
3231 xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level);
3232 appendStringInfoChar(result, '\n');
3233
3234 if (xmlschema)
3235 appendStringInfo(result, "%s\n\n", xmlschema);
3236
3237 SPI_connect();
3238
3240
3241 foreach(cell, relid_list)
3242 {
3243 Oid relid = lfirst_oid(cell);
3244 StringInfo subres;
3245
3246 subres = table_to_xml_internal(relid, NULL, nulls, tableforest,
3247 targetns, false);
3248
3249 appendBinaryStringInfo(result, subres->data, subres->len);
3250 appendStringInfoChar(result, '\n');
3251 }
3252
3253 SPI_finish();
3254
3255 xmldata_root_element_end(result, xmlsn);
3256
3257 return result;
3258}
static List * schema_get_xml_visible_tables(Oid nspid)
Definition: xml.c:2853
static StringInfo table_to_xml_internal(Oid relid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level)
Definition: xml.c:2906

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

3354{
3356 bool nulls = PG_GETARG_BOOL(1);
3357 bool tableforest = PG_GETARG_BOOL(2);
3358 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3359
3361 nulls, tableforest, targetns)));
3362}

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

3310{
3311 Oid nspid;
3312 List *relid_list;
3313 List *tupdesc_list;
3314 ListCell *cell;
3315 StringInfo result;
3316
3317 result = makeStringInfo();
3318
3319 nspid = LookupExplicitNamespace(schemaname, false);
3320
3321 xsd_schema_element_start(result, targetns);
3322
3323 SPI_connect();
3324
3326
3327 tupdesc_list = NIL;
3328 foreach(cell, relid_list)
3329 {
3330 Relation rel;
3331
3333 tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att));
3334 table_close(rel, NoLock);
3335 }
3336
3339
3342 nulls, tableforest, targetns));
3343
3344 xsd_schema_element_end(result);
3345
3346 SPI_finish();
3347
3348 return result;
3349}
static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns)
Definition: xml.c:3659

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

4127{
4128 int i;
4129 char *xmltn;
4130
4131 if (tablename)
4132 xmltn = map_sql_identifier_to_xml_name(tablename, true, false);
4133 else
4134 {
4135 if (tableforest)
4136 xmltn = "row";
4137 else
4138 xmltn = "table";
4139 }
4140
4141 if (tableforest)
4142 xmldata_root_element_start(result, xmltn, NULL, targetns, top_level);
4143 else
4144 appendStringInfoString(result, "<row>\n");
4145
4146 for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++)
4147 {
4148 char *colname;
4149 Datum colval;
4150 bool isnull;
4151
4153 true, false);
4154 colval = SPI_getbinval(SPI_tuptable->vals[rownum],
4156 i,
4157 &isnull);
4158 if (isnull)
4159 {
4160 if (nulls)
4161 appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname);
4162 }
4163 else
4164 appendStringInfo(result, " <%s>%s</%s>\n",
4165 colname,
4168 colname);
4169 }
4170
4171 if (tableforest)
4172 {
4173 xmldata_root_element_end(result, xmltn);
4174 appendStringInfoChar(result, '\n');
4175 }
4176 else
4177 appendStringInfoString(result, "</row>\n\n");
4178}
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1308
char * SPI_fname(TupleDesc tupdesc, int fnumber)
Definition: spi.c:1198

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

2924{
2925 Oid relid = PG_GETARG_OID(0);
2926 bool nulls = PG_GETARG_BOOL(1);
2927 bool tableforest = PG_GETARG_BOOL(2);
2928 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
2929
2931 nulls, tableforest,
2932 targetns, true)));
2933}
#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 3162 of file xml.c.

3163{
3164 Oid relid = PG_GETARG_OID(0);
3165 bool nulls = PG_GETARG_BOOL(1);
3166 bool tableforest = PG_GETARG_BOOL(2);
3167 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3168 Relation rel;
3169 const char *xmlschema;
3170
3171 rel = table_open(relid, AccessShareLock);
3172 xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3173 tableforest, targetns);
3174 table_close(rel, NoLock);
3175
3177 xmlschema, nulls, tableforest,
3178 targetns, true)));
3179}

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

2909{
2910 StringInfoData query;
2911
2912 initStringInfo(&query);
2913 appendStringInfo(&query, "SELECT * FROM %s",
2915 ObjectIdGetDatum(relid))));
2916 return query_to_xml_internal(query.data, get_rel_name(relid),
2917 xmlschema, nulls, tableforest,
2918 targetns, top_level);
2919}
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
static char * DatumGetCString(Datum X)
Definition: postgres.h:345
Datum regclassout(PG_FUNCTION_ARGS)
Definition: regproc.c:951

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

3085{
3086 Oid relid = PG_GETARG_OID(0);
3087 bool nulls = PG_GETARG_BOOL(1);
3088 bool tableforest = PG_GETARG_BOOL(2);
3089 const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
3090 const char *result;
3091 Relation rel;
3092
3093 rel = table_open(relid, AccessShareLock);
3094 result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls,
3095 tableforest, targetns);
3096 table_close(rel, NoLock);
3097
3099}

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

659{
661
663}
const void * data
int xmloption
Definition: xml.c:109
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:1031

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

◆ xml_in()

Datum xml_in ( PG_FUNCTION_ARGS  )

Definition at line 272 of file xml.c.

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

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

1168{
1169#ifdef USE_LIBXML
1170 xmlDocPtr doc;
1171 ErrorSaveContext escontext = {T_ErrorSaveContext};
1172
1173 /*
1174 * We'll report "true" if no soft error is reported by xml_parse().
1175 */
1176 doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true,
1177 GetDatabaseEncoding(), NULL, NULL, (Node *) &escontext);
1178 if (doc)
1179 xmlFreeDoc(doc);
1180
1181 return !escontext.error_occurred;
1182#else /* not USE_LIBXML */
1184 return false;
1185#endif /* not USE_LIBXML */
1186}
void * arg
@ XMLOPTION_DOCUMENT
Definition: primnodes.h:1603
bool error_occurred
Definition: miscnodes.h:47
Definition: nodes.h:135

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

4655{
4656#ifdef USE_LIBXML
4658
4659 PG_RETURN_BOOL(wellformed_xml(data, xmloption));
4660#else
4662 return 0;
4663#endif /* not USE_LIBXML */
4664}
#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 4680 of file xml.c.

4681{
4682#ifdef USE_LIBXML
4684
4685 PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT));
4686#else
4688 return 0;
4689#endif /* not USE_LIBXML */
4690}
@ XMLOPTION_CONTENT
Definition: primnodes.h:1604

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

4668{
4669#ifdef USE_LIBXML
4671
4672 PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT));
4673#else
4675 return 0;
4676#endif /* not USE_LIBXML */
4677}

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

356{
358
359 /*
360 * xml_out removes the encoding property in all cases. This is because we
361 * cannot control from here whether the datum will be converted to a
362 * different client encoding, so we'd do more harm than good by including
363 * it.
364 */
366}
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int x
Definition: isn.c:75
static char * xml_out_internal(xmltype *x, pg_enc target_encoding)
Definition: xml.c:311
#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 311 of file xml.c.

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

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

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

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

438{
440 char *outval;
442
443 /*
444 * xml_out_internal doesn't convert the encoding, it just prints the right
445 * declaration. pq_sendtext will do the conversion.
446 */
448
450 pq_sendtext(&buf, outval, strlen(outval));
451 pfree(outval);
453}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
int pg_get_client_encoding(void)
Definition: mbutils.c:337
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c: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 490 of file xml.c.

491{
492#ifdef USE_LIBXML
494 char *argdata = VARDATA_ANY(arg);
497 int i;
498
499 /* check for "--" in string or "-" at the end */
500 for (i = 1; i < len; i++)
501 {
502 if (argdata[i] == '-' && argdata[i - 1] == '-')
504 (errcode(ERRCODE_INVALID_XML_COMMENT),
505 errmsg("invalid XML comment")));
506 }
507 if (len > 0 && argdata[len - 1] == '-')
509 (errcode(ERRCODE_INVALID_XML_COMMENT),
510 errmsg("invalid XML comment")));
511
513 appendStringInfoString(&buf, "<!--");
516
518#else
520 return 0;
521#endif
522}
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3078

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

575{
576#ifdef USE_LIBXML
577 int global_standalone = 1;
578 xmlChar *global_version = NULL;
579 bool global_version_no_value = false;
581 ListCell *v;
582
584 foreach(v, args)
585 {
587 size_t len;
588 xmlChar *version;
589 int standalone;
590 char *str;
591
592 len = VARSIZE(x) - VARHDRSZ;
593 str = text_to_cstring((text *) x);
594
595 parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
596
597 if (standalone == 0 && global_standalone == 1)
598 global_standalone = 0;
599 if (standalone < 0)
600 global_standalone = -1;
601
602 if (!version)
603 global_version_no_value = true;
604 else if (!global_version)
605 global_version = version;
606 else if (xmlStrcmp(version, global_version) != 0)
607 global_version_no_value = true;
608
610 pfree(str);
611 }
612
613 if (!global_version_no_value || global_standalone >= 0)
614 {
615 StringInfoData buf2;
616
617 initStringInfo(&buf2);
618
619 print_xml_decl(&buf2,
620 (!global_version_no_value) ? global_version : NULL,
621 0,
622 global_standalone);
623
624 appendBinaryStringInfo(&buf2, buf.data, buf.len);
625 buf = buf2;
626 }
627
628 return stringinfo_to_xmltype(&buf);
629#else
631 return NULL;
632#endif
633}
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Size VARSIZE(const void *PTR)
Definition: varatt.h:298
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 640 of file xml.c.

641{
642 if (PG_ARGISNULL(0))
643 {
644 if (PG_ARGISNULL(1))
646 else
648 }
649 else if (PG_ARGISNULL(1))
651 else
653 PG_GETARG_XML_P(1))));
654}
#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:574

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

3033{
3034 appendStringInfo(result, "</%s>\n", eltname);
3035}

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

3008{
3009 /* This isn't really wrong but currently makes no sense. */
3010 Assert(top_level || !xmlschema);
3011
3012 appendStringInfo(result, "<%s", eltname);
3013 if (top_level)
3014 {
3015 appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\"");
3016 if (strlen(targetns) > 0)
3017 appendStringInfo(result, " xmlns=\"%s\"", targetns);
3018 }
3019 if (xmlschema)
3020 {
3021 /* FIXME: better targets */
3022 if (strlen(targetns) > 0)
3023 appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns);
3024 else
3025 appendStringInfoString(result, " xsi:noNamespaceSchemaLocation=\"#\"");
3026 }
3027 appendStringInfoString(result, ">\n");
3028}
#define NAMESPACE_XSI
Definition: xml.c:243

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

896{
897#ifdef USE_LIBXML
898 xmltype *result;
899 List *named_arg_strings;
900 List *arg_strings;
901 int i;
902 ListCell *arg;
903 ListCell *narg;
904 PgXmlErrorContext *xmlerrcxt;
905 volatile xmlBufferPtr buf = NULL;
906 volatile xmlTextWriterPtr writer = NULL;
907
908 /*
909 * All arguments are already evaluated, and their values are passed in the
910 * named_argvalue/named_argnull or argvalue/argnull arrays. This avoids
911 * issues if one of the arguments involves a call to some other function
912 * or subsystem that wants to use libxml on its own terms. We examine the
913 * original XmlExpr to identify the numbers and types of the arguments.
914 */
915 named_arg_strings = NIL;
916 i = 0;
917 foreach(arg, xexpr->named_args)
918 {
919 Expr *e = (Expr *) lfirst(arg);
920 char *str;
921
922 if (named_argnull[i])
923 str = NULL;
924 else
925 str = map_sql_value_to_xml_value(named_argvalue[i],
926 exprType((Node *) e),
927 false);
928 named_arg_strings = lappend(named_arg_strings, str);
929 i++;
930 }
931
932 arg_strings = NIL;
933 i = 0;
934 foreach(arg, xexpr->args)
935 {
936 Expr *e = (Expr *) lfirst(arg);
937 char *str;
938
939 /* here we can just forget NULL elements immediately */
940 if (!argnull[i])
941 {
942 str = map_sql_value_to_xml_value(argvalue[i],
943 exprType((Node *) e),
944 true);
945 arg_strings = lappend(arg_strings, str);
946 }
947 i++;
948 }
949
951
952 PG_TRY();
953 {
954 buf = xmlBufferCreate();
955 if (buf == NULL || xmlerrcxt->err_occurred)
956 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
957 "could not allocate xmlBuffer");
958 writer = xmlNewTextWriterMemory(buf, 0);
959 if (writer == NULL || xmlerrcxt->err_occurred)
960 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
961 "could not allocate xmlTextWriter");
962
963 if (xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name) < 0 ||
964 xmlerrcxt->err_occurred)
965 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
966 "could not start xml element");
967
968 forboth(arg, named_arg_strings, narg, xexpr->arg_names)
969 {
970 char *str = (char *) lfirst(arg);
971 char *argname = strVal(lfirst(narg));
972
973 if (str)
974 {
975 if (xmlTextWriterWriteAttribute(writer,
976 (xmlChar *) argname,
977 (xmlChar *) str) < 0 ||
978 xmlerrcxt->err_occurred)
979 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
980 "could not write xml attribute");
981 }
982 }
983
984 foreach(arg, arg_strings)
985 {
986 char *str = (char *) lfirst(arg);
987
988 if (xmlTextWriterWriteRaw(writer, (xmlChar *) str) < 0 ||
989 xmlerrcxt->err_occurred)
990 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
991 "could not write raw xml text");
992 }
993
994 if (xmlTextWriterEndElement(writer) < 0 ||
995 xmlerrcxt->err_occurred)
996 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
997 "could not end xml element");
998
999 /* we MUST do this now to flush data out to the buffer ... */
1000 xmlFreeTextWriter(writer);
1001 writer = NULL;
1002
1003 result = xmlBuffer_to_xmltype(buf);
1004 }
1005 PG_CATCH();
1006 {
1007 if (writer)
1008 xmlFreeTextWriter(writer);
1009 if (buf)
1010 xmlBufferFree(buf);
1011
1012 pg_xml_done(xmlerrcxt, true);
1013
1014 PG_RE_THROW();
1015 }
1016 PG_END_TRY();
1017
1018 xmlBufferFree(buf);
1019
1020 pg_xml_done(xmlerrcxt, false);
1021
1022 return result;
1023#else
1025 return NULL;
1026#endif
1027}
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:1619
List * named_args
Definition: primnodes.h:1615
#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 4589 of file xml.c.

4590{
4591#ifdef USE_LIBXML
4592 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4594 int res_nitems;
4595
4596 xpath_internal(xpath_expr_text, data, NULL,
4597 &res_nitems, NULL);
4598
4599 PG_RETURN_BOOL(res_nitems > 0);
4600#else
4602 return 0;
4603#endif
4604}

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

1032{
1033#ifdef USE_LIBXML
1034 xmlDocPtr doc;
1035
1036 doc = xml_parse(data, xmloption_arg, preserve_whitespace,
1037 GetDatabaseEncoding(), NULL, NULL, NULL);
1038 xmlFreeDoc(doc);
1039
1040 return (xmltype *) data;
1041#else
1043 return NULL;
1044#endif
1045}

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

1050{
1051#ifdef USE_LIBXML
1052 xmltype *result;
1054
1055 if (pg_strcasecmp(target, "xml") == 0)
1056 ereport(ERROR,
1057 (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
1058 errmsg("invalid XML processing instruction"),
1059 errdetail("XML processing instruction target name cannot be \"%s\".", target)));
1060
1061 /*
1062 * Following the SQL standard, the null check comes after the syntax check
1063 * above.
1064 */
1065 *result_is_null = arg_is_null;
1066 if (*result_is_null)
1067 return NULL;
1068
1070
1071 appendStringInfo(&buf, "<?%s", target);
1072
1073 if (arg != NULL)
1074 {
1075 char *string;
1076
1077 string = text_to_cstring(arg);
1078 if (strstr(string, "?>") != NULL)
1079 ereport(ERROR,
1080 (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
1081 errmsg("invalid XML processing instruction"),
1082 errdetail("XML processing instruction cannot contain \"?>\".")));
1083
1085 appendStringInfoString(&buf, string + strspn(string, " "));
1086 pfree(string);
1087 }
1089
1090 result = stringinfo_to_xmltype(&buf);
1091 pfree(buf.data);
1092 return result;
1093#else
1095 return NULL;
1096#endif
1097}
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 1101 of file xml.c.

1102{
1103#ifdef USE_LIBXML
1104 char *str;
1105 size_t len;
1106 xmlChar *orig_version;
1107 int orig_standalone;
1109
1110 len = VARSIZE(data) - VARHDRSZ;
1112
1113 parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
1114
1115 if (version)
1116 orig_version = xml_text2xmlChar(version);
1117 else
1118 orig_version = NULL;
1119
1120 switch (standalone)
1121 {
1122 case XML_STANDALONE_YES:
1123 orig_standalone = 1;
1124 break;
1125 case XML_STANDALONE_NO:
1126 orig_standalone = 0;
1127 break;
1129 orig_standalone = -1;
1130 break;
1132 /* leave original value */
1133 break;
1134 }
1135
1137 print_xml_decl(&buf, orig_version, 0, orig_standalone);
1139
1140 return stringinfo_to_xmltype(&buf);
1141#else
1143 return NULL;
1144#endif
1145}
@ 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 5124 of file xml.c.

5125{
5126#ifdef USE_LIBXML
5127 XmlTableBuilderData *xtCxt;
5128
5129 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque");
5130
5131 /* Propagate our own error context to libxml2 */
5132 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
5133
5134 if (xtCxt->xpathscomp != NULL)
5135 {
5136 int i;
5137
5138 for (i = 0; i < xtCxt->natts; i++)
5139 if (xtCxt->xpathscomp[i] != NULL)
5140 xmlXPathFreeCompExpr(xtCxt->xpathscomp[i]);
5141 }
5142
5143 if (xtCxt->xpathobj != NULL)
5144 xmlXPathFreeObject(xtCxt->xpathobj);
5145 if (xtCxt->xpathcomp != NULL)
5146 xmlXPathFreeCompExpr(xtCxt->xpathcomp);
5147 if (xtCxt->xpathcxt != NULL)
5148 xmlXPathFreeContext(xtCxt->xpathcxt);
5149 if (xtCxt->doc != NULL)
5150 xmlFreeDoc(xtCxt->doc);
5151 if (xtCxt->ctxt != NULL)
5152 xmlFreeParserCtxt(xtCxt->ctxt);
5153
5154 pg_xml_done(xtCxt->xmlerrcxt, true);
5155
5156 /* not valid anymore */
5157 xtCxt->magic = 0;
5158 state->opaque = NULL;
5159
5160#else
5162#endif /* not USE_LIBXML */
5163}
Definition: regguts.h:323

References i, NO_XML_SUPPORT, and pg_xml_done().

◆ XmlTableFetchRow()

static bool XmlTableFetchRow ( struct TableFuncScanState state)
static

Definition at line 4927 of file xml.c.

4928{
4929#ifdef USE_LIBXML
4930 XmlTableBuilderData *xtCxt;
4931
4932 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow");
4933
4934 /* Propagate our own error context to libxml2 */
4935 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
4936
4937 if (xtCxt->xpathobj == NULL)
4938 {
4939 xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
4940 if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4941 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4942 "could not create XPath object");
4943
4944 xtCxt->row_count = 0;
4945 }
4946
4947 if (xtCxt->xpathobj->type == XPATH_NODESET)
4948 {
4949 if (xtCxt->xpathobj->nodesetval != NULL)
4950 {
4951 if (xtCxt->row_count++ < xtCxt->xpathobj->nodesetval->nodeNr)
4952 return true;
4953 }
4954 }
4955
4956 return false;
4957#else
4959 return false;
4960#endif /* not USE_LIBXML */
4961}

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

4974{
4975#ifdef USE_LIBXML
4976 Datum result = (Datum) 0;
4977 XmlTableBuilderData *xtCxt;
4978 volatile xmlXPathObjectPtr xpathobj = NULL;
4979
4980 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableGetValue");
4981
4982 Assert(xtCxt->xpathobj &&
4983 xtCxt->xpathobj->type == XPATH_NODESET &&
4984 xtCxt->xpathobj->nodesetval != NULL);
4985
4986 /* Propagate our own error context to libxml2 */
4987 xmlSetStructuredErrorFunc(xtCxt->xmlerrcxt, xml_errorHandler);
4988
4989 *isnull = false;
4990
4991 Assert(xtCxt->xpathscomp[colnum] != NULL);
4992
4993 PG_TRY();
4994 {
4995 xmlNodePtr cur;
4996 char *cstr = NULL;
4997
4998 /* Set current node as entry point for XPath evaluation */
4999 cur = xtCxt->xpathobj->nodesetval->nodeTab[xtCxt->row_count - 1];
5000 xtCxt->xpathcxt->node = cur;
5001
5002 /* Evaluate column path */
5003 xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
5004 if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
5005 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
5006 "could not create XPath object");
5007
5008 /*
5009 * There are four possible cases, depending on the number of nodes
5010 * returned by the XPath expression and the type of the target column:
5011 * a) XPath returns no nodes. b) The target type is XML (return all
5012 * as XML). For non-XML return types: c) One node (return content).
5013 * d) Multiple nodes (error).
5014 */
5015 if (xpathobj->type == XPATH_NODESET)
5016 {
5017 int count = 0;
5018
5019 if (xpathobj->nodesetval != NULL)
5020 count = xpathobj->nodesetval->nodeNr;
5021
5022 if (xpathobj->nodesetval == NULL || count == 0)
5023 {
5024 *isnull = true;
5025 }
5026 else
5027 {
5028 if (typid == XMLOID)
5029 {
5030 text *textstr;
5032
5033 /* Concatenate serialized values */
5035 for (int i = 0; i < count; i++)
5036 {
5037 textstr =
5038 xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],
5039 xtCxt->xmlerrcxt);
5040
5041 appendStringInfoText(&str, textstr);
5042 }
5043 cstr = str.data;
5044 }
5045 else
5046 {
5047 xmlChar *str;
5048
5049 if (count > 1)
5050 ereport(ERROR,
5051 (errcode(ERRCODE_CARDINALITY_VIOLATION),
5052 errmsg("more than one value returned by column XPath expression")));
5053
5054 str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);
5055 cstr = str ? xml_pstrdup_and_free(str) : "";
5056 }
5057 }
5058 }
5059 else if (xpathobj->type == XPATH_STRING)
5060 {
5061 /* Content should be escaped when target will be XML */
5062 if (typid == XMLOID)
5063 cstr = escape_xml((char *) xpathobj->stringval);
5064 else
5065 cstr = (char *) xpathobj->stringval;
5066 }
5067 else if (xpathobj->type == XPATH_BOOLEAN)
5068 {
5069 char typcategory;
5070 bool typispreferred;
5071 xmlChar *str;
5072
5073 /* Allow implicit casting from boolean to numbers */
5074 get_type_category_preferred(typid, &typcategory, &typispreferred);
5075
5076 if (typcategory != TYPCATEGORY_NUMERIC)
5077 str = xmlXPathCastBooleanToString(xpathobj->boolval);
5078 else
5079 str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval));
5080
5081 cstr = xml_pstrdup_and_free(str);
5082 }
5083 else if (xpathobj->type == XPATH_NUMBER)
5084 {
5085 xmlChar *str;
5086
5087 str = xmlXPathCastNumberToString(xpathobj->floatval);
5088 cstr = xml_pstrdup_and_free(str);
5089 }
5090 else
5091 elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
5092
5093 /*
5094 * By here, either cstr contains the result value, or the isnull flag
5095 * has been set.
5096 */
5097 Assert(cstr || *isnull);
5098
5099 if (!*isnull)
5100 result = InputFunctionCall(&state->in_functions[colnum],
5101 cstr,
5102 state->typioparams[colnum],
5103 typmod);
5104 }
5105 PG_FINALLY();
5106 {
5107 if (xpathobj != NULL)
5108 xmlXPathFreeObject(xpathobj);
5109 }
5110 PG_END_TRY();
5111
5112 return result;
5113#else
5115 return 0;
5116#endif /* not USE_LIBXML */
5117}
struct cursor * cur
Definition: ecpg.c:29
#define PG_FINALLY(...)
Definition: elog.h:389
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:2877

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

4730{
4731#ifdef USE_LIBXML
4732 volatile xmlParserCtxtPtr ctxt = NULL;
4733 XmlTableBuilderData *xtCxt;
4734 PgXmlErrorContext *xmlerrcxt;
4735
4736 xtCxt = palloc0(sizeof(XmlTableBuilderData));
4737 xtCxt->magic = XMLTABLE_CONTEXT_MAGIC;
4738 xtCxt->natts = natts;
4739 xtCxt->xpathscomp = palloc0(sizeof(xmlXPathCompExprPtr) * natts);
4740
4742
4743 PG_TRY();
4744 {
4745 xmlInitParser();
4746
4747 ctxt = xmlNewParserCtxt();
4748 if (ctxt == NULL || xmlerrcxt->err_occurred)
4749 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4750 "could not allocate parser context");
4751 }
4752 PG_CATCH();
4753 {
4754 if (ctxt != NULL)
4755 xmlFreeParserCtxt(ctxt);
4756
4757 pg_xml_done(xmlerrcxt, true);
4758
4759 PG_RE_THROW();
4760 }
4761 PG_END_TRY();
4762
4763 xtCxt->xmlerrcxt = xmlerrcxt;
4764 xtCxt->ctxt = ctxt;
4765
4766 state->opaque = xtCxt;
4767#else
4769#endif /* not USE_LIBXML */
4770}
void * palloc0(Size size)
Definition: mcxt.c:1395

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

4893{
4894#ifdef USE_LIBXML
4895 XmlTableBuilderData *xtCxt;
4896 xmlChar *xstr;
4897
4898 Assert(path);
4899
4900 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetColumnFilter");
4901
4902 if (*path == '\0')
4903 ereport(ERROR,
4904 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
4905 errmsg("column path filter must not be empty string")));
4906
4907 xstr = pg_xmlCharStrndup(path, strlen(path));
4908
4909 /* We require XmlTableSetDocument to have been done already */
4910 Assert(xtCxt->xpathcxt != NULL);
4911
4912 xtCxt->xpathscomp[colnum] = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
4913 if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4914 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4915 "invalid XPath expression");
4916#else
4918#endif /* not USE_LIBXML */
4919}

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

◆ XmlTableSetDocument()

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

Definition at line 4777 of file xml.c.

4778{
4779#ifdef USE_LIBXML
4780 XmlTableBuilderData *xtCxt;
4781 xmltype *xmlval = DatumGetXmlP(value);
4782 char *str;
4783 xmlChar *xstr;
4784 int length;
4785 volatile xmlDocPtr doc = NULL;
4786 volatile xmlXPathContextPtr xpathcxt = NULL;
4787
4788 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetDocument");
4789
4790 /*
4791 * Use out function for casting to string (remove encoding property). See
4792 * comment in xml_out.
4793 */
4794 str = xml_out_internal(xmlval, 0);
4795
4796 length = strlen(str);
4797 xstr = pg_xmlCharStrndup(str, length);
4798
4799 PG_TRY();
4800 {
4801 doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
4802 if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
4803 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
4804 "could not parse XML document");
4805 xpathcxt = xmlXPathNewContext(doc);
4806 if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred)
4807 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
4808 "could not allocate XPath context");
4809 xpathcxt->node = (xmlNodePtr) doc;
4810 }
4811 PG_CATCH();
4812 {
4813 if (xpathcxt != NULL)
4814 xmlXPathFreeContext(xpathcxt);
4815 if (doc != NULL)
4816 xmlFreeDoc(doc);
4817
4818 PG_RE_THROW();
4819 }
4820 PG_END_TRY();
4821
4822 xtCxt->doc = doc;
4823 xtCxt->xpathcxt = xpathcxt;
4824#else
4826#endif /* not USE_LIBXML */
4827}

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

4835{
4836#ifdef USE_LIBXML
4837 XmlTableBuilderData *xtCxt;
4838
4839 if (name == NULL)
4840 ereport(ERROR,
4841 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4842 errmsg("DEFAULT namespace is not supported")));
4843 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetNamespace");
4844
4845 if (xmlXPathRegisterNs(xtCxt->xpathcxt,
4846 pg_xmlCharStrndup(name, strlen(name)),
4847 pg_xmlCharStrndup(uri, strlen(uri))))
4848 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4849 "could not set XML namespace");
4850#else
4852#endif /* not USE_LIBXML */
4853}

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

4861{
4862#ifdef USE_LIBXML
4863 XmlTableBuilderData *xtCxt;
4864 xmlChar *xstr;
4865
4866 xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableSetRowFilter");
4867
4868 if (*path == '\0')
4869 ereport(ERROR,
4870 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
4871 errmsg("row path filter must not be empty string")));
4872
4873 xstr = pg_xmlCharStrndup(path, strlen(path));
4874
4875 /* We require XmlTableSetDocument to have been done already */
4876 Assert(xtCxt->xpathcxt != NULL);
4877
4878 xtCxt->xpathcomp = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
4879 if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4880 xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
4881 "invalid XPath expression");
4882#else
4884#endif /* not USE_LIBXML */
4885}

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

◆ xmltext()

Datum xmltext ( PG_FUNCTION_ARGS  )

Definition at line 526 of file xml.c.

527{
528#ifdef USE_LIBXML
530 text *result;
531 volatile xmlChar *xmlbuf = NULL;
532 PgXmlErrorContext *xmlerrcxt;
533
534 /* First we gotta spin up some error handling. */
536
537 PG_TRY();
538 {
539 xmlbuf = xmlEncodeSpecialChars(NULL, xml_text2xmlChar(arg));
540
541 if (xmlbuf == NULL || xmlerrcxt->err_occurred)
542 xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
543 "could not allocate xmlChar");
544
545 result = cstring_to_text_with_len((const char *) xmlbuf,
546 xmlStrlen((const xmlChar *) xmlbuf));
547 }
548 PG_CATCH();
549 {
550 if (xmlbuf)
551 xmlFree((xmlChar *) xmlbuf);
552
553 pg_xml_done(xmlerrcxt, true);
554 PG_RE_THROW();
555 }
556 PG_END_TRY();
557
558 xmlFree((xmlChar *) xmlbuf);
559 pg_xml_done(xmlerrcxt, false);
560
561 PG_RETURN_XML_P(result);
562#else
564 return 0;
565#endif /* not USE_LIBXML */
566}

References arg, cstring_to_text_with_len(), ERROR, NO_XML_SUPPORT, PG_CATCH, PG_END_TRY, PG_GETARG_TEXT_PP, PG_RE_THROW, PG_RETURN_XML_P, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, and xml_ereport().

◆ xmltotext()

Datum xmltotext ( PG_FUNCTION_ARGS  )

Definition at line 667 of file xml.c.

668{
670
671 /* It's actually binary compatible. */
673}
#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 677 of file xml.c.

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

1158{
1159 ereport(ERROR,
1160 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1161 errmsg("xmlvalidate is not implemented")));
1162 return 0;
1163}

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

◆ xpath()

Datum xpath ( PG_FUNCTION_ARGS  )

Definition at line 4566 of file xml.c.

4567{
4568#ifdef USE_LIBXML
4569 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4571 ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4572 ArrayBuildState *astate;
4573
4574 astate = initArrayResult(XMLOID, CurrentMemoryContext, true);
4575 xpath_internal(xpath_expr_text, data, namespaces,
4576 NULL, astate);
4578#else
4580 return 0;
4581#endif
4582}
#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:160

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

4613{
4614#ifdef USE_LIBXML
4615 text *xpath_expr_text = PG_GETARG_TEXT_PP(0);
4617 ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2);
4618 int res_nitems;
4619
4620 xpath_internal(xpath_expr_text, data, namespaces,
4621 &res_nitems, NULL);
4622
4623 PG_RETURN_BOOL(res_nitems > 0);
4624#else
4626 return 0;
4627#endif
4628}

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

3302{
3303 appendStringInfoString(result, "</xsd:schema>");
3304}

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

3285{
3287 "<xsd:schema\n"
3288 " xmlns:xsd=\"" NAMESPACE_XSD "\"");
3289 if (strlen(targetns) > 0)
3290 appendStringInfo(result,
3291 "\n"
3292 " targetNamespace=\"%s\"\n"
3293 " elementFormDefault=\"qualified\"",
3294 targetns);
3296 ">\n\n");
3297}
#define NAMESPACE_XSD
Definition: xml.c:242

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 108 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 109 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:4729
static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, const char *uri)
Definition: xml.c:4834
static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path)
Definition: xml.c:4860
static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
Definition: xml.c:4972
static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value)
Definition: xml.c:4777
static void XmlTableDestroyOpaque(struct TableFuncScanState *state)
Definition: xml.c:5124
static bool XmlTableFetchRow(struct TableFuncScanState *state)
Definition: xml.c:4927
static void XmlTableSetColumnFilter(struct TableFuncScanState *state, const char *path, int colnum)
Definition: xml.c:4892

Definition at line 222 of file xml.c.

Referenced by ExecInitTableFuncScan().