#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "executor/executor.h"
#include "executor/spi.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xml.h"
Go to the source code of this file.
Defines | |
#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 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 (int rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level) |
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 xmltype * | stringinfo_to_xmltype (StringInfo buf) |
static xmltype * | cstring_to_xmltype (const char *string) |
Datum | xmlcomment (PG_FUNCTION_ARGS) |
xmltype * | xmlconcat (List *args) |
Datum | xmlconcat2 (PG_FUNCTION_ARGS) |
Datum | texttoxml (PG_FUNCTION_ARGS) |
Datum | xmltotext (PG_FUNCTION_ARGS) |
text * | xmltotext_with_xmloption (xmltype *data, XmlOptionType xmloption_arg) |
xmltype * | xmlelement (XmlExprState *xmlExpr, ExprContext *econtext) |
xmltype * | xmlparse (text *data, XmlOptionType xmloption_arg, bool preserve_whitespace) |
xmltype * | xmlpi (char *target, text *arg, bool arg_is_null, bool *result_is_null) |
xmltype * | xmlroot (xmltype *data, text *version, int standalone) |
Datum | xmlvalidate (PG_FUNCTION_ARGS) |
bool | xml_is_document (xmltype *arg) |
char * | map_sql_identifier_to_xml_name (char *ident, bool fully_escaped, bool escape_period) |
static char * | unicode_to_sqlchar (pg_wchar c) |
char * | map_xml_name_to_sql_identifier (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 List * | query_to_oid_list (const char *query) |
static List * | schema_get_xml_visible_tables (Oid nspid) |
static List * | database_get_xml_visible_schemas (void) |
static List * | database_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) |
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) |
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 (char *a, char *b, char *c, char *d) |
Datum | xpath (PG_FUNCTION_ARGS) |
Datum | xmlexists (PG_FUNCTION_ARGS) |
Datum | xpath_exists (PG_FUNCTION_ARGS) |
Datum | xml_is_well_formed (PG_FUNCTION_ARGS) |
Datum | xml_is_well_formed_document (PG_FUNCTION_ARGS) |
Datum | xml_is_well_formed_content (PG_FUNCTION_ARGS) |
Variables | |
int | xmlbinary |
int | xmloption |
#define NAMESPACE_SQLXML "http://standards.iso.org/iso/9075/2003/sqlxml" |
#define NAMESPACE_XSD "http://www.w3.org/2001/XMLSchema" |
Definition at line 176 of file xml.c.
Referenced by xsd_schema_element_start().
#define NAMESPACE_XSI "http://www.w3.org/2001/XMLSchema-instance" |
Definition at line 177 of file xml.c.
Referenced by xmldata_root_element_start().
#define NO_XML_SUPPORT | ( | ) |
ereport(ERROR, \ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ errmsg("unsupported XML feature"), \ errdetail("This functionality requires the server to be built with libxml support."), \ errhint("You need to rebuild PostgreSQL using --with-libxml.")))
Definition at line 167 of file xml.c.
Referenced by map_sql_identifier_to_xml_name(), xml_in(), xml_is_document(), xml_is_well_formed(), xml_is_well_formed_content(), xml_is_well_formed_document(), xml_recv(), xmlcomment(), xmlconcat(), xmlelement(), xmlexists(), xmlparse(), xmlpi(), xmlroot(), xpath(), and xpath_exists().
#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 2306 of file xml.c.
Referenced by database_get_xml_visible_schemas(), and database_get_xml_visible_tables().
#define XML_VISIBLE_SCHEMAS_EXCLUDE "(nspname ~ '^pg_' OR nspname = 'information_schema')" |
static char* _SPI_strdup | ( | const char * | s | ) | [static] |
Definition at line 2207 of file xml.c.
References SPI_palloc().
Referenced by cursor_to_xmlschema(), query_to_xml_and_xmlschema(), and query_to_xmlschema().
{ size_t len = strlen(s) + 1; char *ret = SPI_palloc(len); memcpy(ret, s, len); return ret; }
static xmltype* cstring_to_xmltype | ( | const char * | string | ) | [static] |
Definition at line 405 of file xml.c.
References cstring_to_text().
Referenced by cursor_to_xmlschema(), query_to_xmlschema(), and table_to_xmlschema().
{ return (xmltype *) cstring_to_text(string); }
Datum cursor_to_xml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2375 of file xml.c.
References ereport, errcode(), errmsg(), ERROR, i, initStringInfo(), NULL, 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(), and text_to_cstring().
{ char *name = text_to_cstring(PG_GETARG_TEXT_PP(0)); int32 count = PG_GETARG_INT32(1); bool nulls = PG_GETARG_BOOL(2); bool tableforest = PG_GETARG_BOOL(3); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4)); StringInfoData result; Portal portal; int i; initStringInfo(&result); SPI_connect(); portal = SPI_cursor_find(name); if (portal == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_CURSOR), errmsg("cursor \"%s\" does not exist", name))); SPI_cursor_fetch(portal, true, count); for (i = 0; i < SPI_processed; i++) SPI_sql_row_to_xmlelement(i, &result, NULL, nulls, tableforest, targetns, true); SPI_finish(); PG_RETURN_XML_P(stringinfo_to_xmltype(&result)); }
Datum cursor_to_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2547 of file xml.c.
References _SPI_strdup(), cstring_to_xmltype(), ereport, errcode(), errmsg(), ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, SPI_connect(), SPI_cursor_find(), SPI_finish(), text_to_cstring(), and PortalData::tupDesc.
{ char *name = text_to_cstring(PG_GETARG_TEXT_PP(0)); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); const char *xmlschema; Portal portal; SPI_connect(); portal = SPI_cursor_find(name); if (portal == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_CURSOR), errmsg("cursor \"%s\" does not exist", name))); xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc, InvalidOid, nulls, tableforest, targetns)); SPI_finish(); PG_RETURN_XML_P(cstring_to_xmltype(xmlschema)); }
static List* database_get_xml_visible_schemas | ( | void | ) | [static] |
Definition at line 2310 of file xml.c.
References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.
Referenced by database_to_xml_internal(), and database_to_xmlschema_internal().
{ return query_to_oid_list(XML_VISIBLE_SCHEMAS " ORDER BY nspname;"); }
static List* database_get_xml_visible_tables | ( | void | ) | [static] |
Definition at line 2317 of file xml.c.
References query_to_oid_list(), and XML_VISIBLE_SCHEMAS.
Referenced by database_to_xmlschema_internal().
{ /* At the moment there is no order required here. */ return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class WHERE relkind IN ('r', 'm', 'v') AND pg_catalog.has_table_privilege (pg_class.oid, 'SELECT') AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");"); }
Datum database_to_xml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2854 of file xml.c.
References database_to_xml_internal(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().
{ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2)); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xml_internal(NULL, nulls, tableforest, targetns))); }
Datum database_to_xml_and_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2921 of file xml.c.
References StringInfoData::data, database_to_xml_internal(), database_to_xmlschema_internal(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().
{ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2)); StringInfo xmlschema; xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xml_internal(xmlschema->data, nulls, tableforest, targetns))); }
static StringInfo database_to_xml_internal | ( | const char * | xmlschema, | |
bool | nulls, | |||
bool | tableforest, | |||
const char * | targetns | |||
) | [static] |
Definition at line 2808 of file xml.c.
References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, database_get_xml_visible_schemas(), get_database_name(), lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), MyDatabaseId, NULL, schema_to_xml_internal(), SPI_connect(), SPI_finish(), SPI_pop(), SPI_push(), xmldata_root_element_end(), and xmldata_root_element_start().
Referenced by database_to_xml(), and database_to_xml_and_xmlschema().
{ StringInfo result; List *nspid_list; ListCell *cell; char *xmlcn; xmlcn = map_sql_identifier_to_xml_name(get_database_name(MyDatabaseId), true, false); result = makeStringInfo(); xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true); appendStringInfoString(result, "\n"); if (xmlschema) appendStringInfo(result, "%s\n\n", xmlschema); SPI_connect(); nspid_list = database_get_xml_visible_schemas(); SPI_push(); foreach(cell, nspid_list) { Oid nspid = lfirst_oid(cell); StringInfo subres; subres = schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, false); appendStringInfoString(result, subres->data); appendStringInfoChar(result, '\n'); } SPI_pop(); SPI_finish(); xmldata_root_element_end(result, xmlcn); return result; }
Datum database_to_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2909 of file xml.c.
References database_to_xmlschema_internal(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, stringinfo_to_xmltype(), and text_to_cstring().
{ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2)); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xmlschema_internal(nulls, tableforest, targetns))); }
static StringInfo database_to_xmlschema_internal | ( | bool | nulls, | |
bool | tableforest, | |||
const char * | targetns | |||
) | [static] |
Definition at line 2866 of file xml.c.
References AccessShareLock, appendStringInfoString(), CreateTupleDescCopy(), database_get_xml_visible_schemas(), database_get_xml_visible_tables(), heap_close, heap_open(), lappend(), lfirst_oid, makeStringInfo(), map_sql_catalog_to_xmlschema_types(), map_sql_typecoll_to_xmlschema_types(), NoLock, RelationData::rd_att, SPI_connect(), SPI_finish(), xsd_schema_element_end(), and xsd_schema_element_start().
Referenced by database_to_xml_and_xmlschema(), and database_to_xmlschema().
{ List *relid_list; List *nspid_list; List *tupdesc_list; ListCell *cell; StringInfo result; result = makeStringInfo(); xsd_schema_element_start(result, targetns); SPI_connect(); relid_list = database_get_xml_visible_tables(); nspid_list = database_get_xml_visible_schemas(); tupdesc_list = NIL; foreach(cell, relid_list) { Relation rel; rel = heap_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); heap_close(rel, NoLock); } appendStringInfoString(result, map_sql_typecoll_to_xmlschema_types(tupdesc_list)); appendStringInfoString(result, map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns)); xsd_schema_element_end(result); SPI_finish(); return result; }
char* escape_xml | ( | const char * | str | ) |
Definition at line 2175 of file xml.c.
References appendStringInfoCharMacro, appendStringInfoString(), StringInfoData::data, and initStringInfo().
Referenced by ExplainProperty(), ExplainPropertyList(), and map_sql_value_to_xml_value().
{ StringInfoData buf; const char *p; initStringInfo(&buf); for (p = str; *p; p++) { switch (*p) { case '&': appendStringInfoString(&buf, "&"); break; case '<': appendStringInfoString(&buf, "<"); break; case '>': appendStringInfoString(&buf, ">"); break; case '\r': appendStringInfoString(&buf, "
"); break; default: appendStringInfoCharMacro(&buf, *p); break; } } return buf.data; }
static char* map_multipart_sql_identifier_to_xml_name | ( | char * | a, | |
char * | b, | |||
char * | c, | |||
char * | d | |||
) | [static] |
Definition at line 2940 of file xml.c.
References appendStringInfo(), 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().
{ StringInfoData result; initStringInfo(&result); if (a) appendStringInfo(&result, "%s", map_sql_identifier_to_xml_name(a, true, true)); if (b) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(b, true, true)); if (c) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(c, true, true)); if (d) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(d, true, true)); return result.data; }
static const char * map_sql_catalog_to_xmlschema_types | ( | List * | nspid_list, | |
bool | nulls, | |||
bool | tableforest, | |||
const char * | targetns | |||
) | [static] |
Definition at line 3147 of file xml.c.
References appendStringInfo(), appendStringInfoString(), StringInfoData::data, get_database_name(), get_namespace_name(), initStringInfo(), lfirst_oid, map_multipart_sql_identifier_to_xml_name(), map_sql_identifier_to_xml_name(), MyDatabaseId, and NULL.
Referenced by database_to_xmlschema_internal().
{ char *dbname; char *xmlcn; char *catalogtypename; StringInfoData result; ListCell *cell; dbname = get_database_name(MyDatabaseId); initStringInfo(&result); xmlcn = map_sql_identifier_to_xml_name(dbname, true, false); catalogtypename = map_multipart_sql_identifier_to_xml_name("CatalogType", dbname, NULL, NULL); appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n", catalogtypename); appendStringInfoString(&result, " <xsd:all>\n"); foreach(cell, nspid_list) { Oid nspid = lfirst_oid(cell); char *nspname = get_namespace_name(nspid); char *xmlsn = map_sql_identifier_to_xml_name(nspname, true, false); char *schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType", dbname, nspname, NULL); appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\"/>\n", xmlsn, schematypename); } appendStringInfoString(&result, " </xsd:all>\n"); appendStringInfoString(&result, "</xsd:complexType>\n\n"); appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmlcn, catalogtypename); return result.data; }
Definition at line 1836 of file xml.c.
References appendBinaryStringInfo(), appendStringInfo(), Assert, StringInfoData::data, initStringInfo(), NO_XML_SUPPORT, pg_mblen(), and pg_strncasecmp().
Referenced by database_to_xml_internal(), map_multipart_sql_identifier_to_xml_name(), map_sql_catalog_to_xmlschema_types(), map_sql_schema_to_xmlschema_types(), map_sql_table_to_xmlschema(), query_to_xml_internal(), schema_to_xml_internal(), SPI_sql_row_to_xmlelement(), and transformXmlExpr().
{ #ifdef USE_LIBXML StringInfoData buf; char *p; /* * SQL/XML doesn't make use of this case anywhere, so it's probably a * mistake. */ Assert(fully_escaped || !escape_period); initStringInfo(&buf); for (p = ident; *p; p += pg_mblen(p)) { if (*p == ':' && (p == ident || fully_escaped)) appendStringInfo(&buf, "_x003A_"); else if (*p == '_' && *(p + 1) == 'x') appendStringInfo(&buf, "_x005F_"); else if (fully_escaped && p == ident && pg_strncasecmp(p, "xml", 3) == 0) { if (*p == 'x') appendStringInfo(&buf, "_x0078_"); else appendStringInfo(&buf, "_x0058_"); } else if (escape_period && *p == '.') appendStringInfo(&buf, "_x002E_"); else { pg_wchar u = sqlchar_to_unicode(p); if ((p == ident) ? !is_valid_xml_namefirst(u) : !is_valid_xml_namechar(u)) appendStringInfo(&buf, "_x%04X_", (unsigned int) u); else appendBinaryStringInfo(&buf, p, pg_mblen(p)); } } return buf.data; #else /* not USE_LIBXML */ NO_XML_SUPPORT(); return NULL; #endif /* not USE_LIBXML */ }
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 3074 of file xml.c.
References appendStringInfo(), appendStringInfoString(), StringInfoData::data, get_database_name(), get_namespace_name(), get_rel_name(), initStringInfo(), lfirst_oid, map_multipart_sql_identifier_to_xml_name(), map_sql_identifier_to_xml_name(), MyDatabaseId, and NULL.
Referenced by schema_to_xmlschema_internal().
{ char *dbname; char *nspname; char *xmlsn; char *schematypename; StringInfoData result; ListCell *cell; dbname = get_database_name(MyDatabaseId); nspname = get_namespace_name(nspid); initStringInfo(&result); xmlsn = map_sql_identifier_to_xml_name(nspname, true, false); schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType", dbname, nspname, NULL); appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n", schematypename); if (!tableforest) appendStringInfoString(&result, " <xsd:all>\n"); else appendStringInfoString(&result, " <xsd:sequence>\n"); foreach(cell, relid_list) { Oid relid = lfirst_oid(cell); char *relname = get_rel_name(relid); char *xmltn = map_sql_identifier_to_xml_name(relname, true, false); char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType", dbname, nspname, relname); if (!tableforest) appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\"/>\n", xmltn, tabletypename); else appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n", xmltn, tabletypename); } if (!tableforest) appendStringInfoString(&result, " </xsd:all>\n"); else appendStringInfoString(&result, " </xsd:sequence>\n"); appendStringInfoString(&result, "</xsd:complexType>\n\n"); appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmlsn, schematypename); return result.data; }
static const char * map_sql_table_to_xmlschema | ( | TupleDesc | tupdesc, | |
Oid | relid, | |||
bool | nulls, | |||
bool | tableforest, | |||
const char * | targetns | |||
) | [static] |
Definition at line 2971 of file xml.c.
References appendStringInfo(), appendStringInfoString(), tupleDesc::attrs, 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, tupleDesc::natts, ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), RELOID, SearchSysCache1, 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().
{ int i; char *xmltn; char *tabletypename; char *rowtypename; StringInfoData result; initStringInfo(&result); if (OidIsValid(relid)) { HeapTuple tuple; Form_pg_class reltuple; tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relid); reltuple = (Form_pg_class) GETSTRUCT(tuple); xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname), true, false); tabletypename = map_multipart_sql_identifier_to_xml_name("TableType", get_database_name(MyDatabaseId), get_namespace_name(reltuple->relnamespace), NameStr(reltuple->relname)); rowtypename = map_multipart_sql_identifier_to_xml_name("RowType", get_database_name(MyDatabaseId), get_namespace_name(reltuple->relnamespace), NameStr(reltuple->relname)); ReleaseSysCache(tuple); } else { if (tableforest) xmltn = "row"; else xmltn = "table"; tabletypename = "TableType"; rowtypename = "RowType"; } xsd_schema_element_start(&result, targetns); appendStringInfoString(&result, map_sql_typecoll_to_xmlschema_types(list_make1(tupdesc))); appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n" " <xsd:sequence>\n", rowtypename); for (i = 0; i < tupdesc->natts; i++) { if (tupdesc->attrs[i]->attisdropped) continue; appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n", map_sql_identifier_to_xml_name(NameStr(tupdesc->attrs[i]->attname), true, false), map_sql_type_to_xml_name(tupdesc->attrs[i]->atttypid, -1), nulls ? " nillable=\"true\"" : " minOccurs=\"0\""); } appendStringInfoString(&result, " </xsd:sequence>\n" "</xsd:complexType>\n\n"); if (!tableforest) { appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n" " <xsd:sequence>\n" " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n" " </xsd:sequence>\n" "</xsd:complexType>\n\n", tabletypename, rowtypename); appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmltn, tabletypename); } else appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmltn, rowtypename); xsd_schema_element_end(&result); return result.data; }
static const char * map_sql_type_to_xml_name | ( | Oid | typeoid, | |
int | typmod | |||
) | [static] |
Definition at line 3204 of file xml.c.
References appendStringInfo(), appendStringInfoString(), BOOLOID, BPCHAROID, StringInfoData::data, DATEOID, elog, ERROR, FLOAT4OID, FLOAT8OID, get_database_name(), get_namespace_name(), GETSTRUCT, HeapTupleIsValid, initStringInfo(), INT2OID, INT4OID, INT8OID, map_multipart_sql_identifier_to_xml_name(), MyDatabaseId, NameStr, NUMERICOID, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, TYPEOID, TYPTYPE_DOMAIN, VARCHAROID, VARHDRSZ, and XMLOID.
Referenced by map_sql_table_to_xmlschema(), and map_sql_type_to_xmlschema_type().
{ StringInfoData result; initStringInfo(&result); switch (typeoid) { case BPCHAROID: if (typmod == -1) appendStringInfo(&result, "CHAR"); else appendStringInfo(&result, "CHAR_%d", typmod - VARHDRSZ); break; case VARCHAROID: if (typmod == -1) appendStringInfo(&result, "VARCHAR"); else appendStringInfo(&result, "VARCHAR_%d", typmod - VARHDRSZ); break; case NUMERICOID: if (typmod == -1) appendStringInfo(&result, "NUMERIC"); else appendStringInfo(&result, "NUMERIC_%d_%d", ((typmod - VARHDRSZ) >> 16) & 0xffff, (typmod - VARHDRSZ) & 0xffff); break; case INT4OID: appendStringInfo(&result, "INTEGER"); break; case INT2OID: appendStringInfo(&result, "SMALLINT"); break; case INT8OID: appendStringInfo(&result, "BIGINT"); break; case FLOAT4OID: appendStringInfo(&result, "REAL"); break; case FLOAT8OID: appendStringInfo(&result, "DOUBLE"); break; case BOOLOID: appendStringInfo(&result, "BOOLEAN"); break; case TIMEOID: if (typmod == -1) appendStringInfo(&result, "TIME"); else appendStringInfo(&result, "TIME_%d", typmod); break; case TIMETZOID: if (typmod == -1) appendStringInfo(&result, "TIME_WTZ"); else appendStringInfo(&result, "TIME_WTZ_%d", typmod); break; case TIMESTAMPOID: if (typmod == -1) appendStringInfo(&result, "TIMESTAMP"); else appendStringInfo(&result, "TIMESTAMP_%d", typmod); break; case TIMESTAMPTZOID: if (typmod == -1) appendStringInfo(&result, "TIMESTAMP_WTZ"); else appendStringInfo(&result, "TIMESTAMP_WTZ_%d", typmod); break; case DATEOID: appendStringInfo(&result, "DATE"); break; case XMLOID: appendStringInfo(&result, "XML"); break; default: { HeapTuple tuple; Form_pg_type typtuple; tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for type %u", typeoid); typtuple = (Form_pg_type) GETSTRUCT(tuple); appendStringInfoString(&result, map_multipart_sql_identifier_to_xml_name((typtuple->typtype == TYPTYPE_DOMAIN) ? "Domain" : "UDT", get_database_name(MyDatabaseId), get_namespace_name(typtuple->typnamespace), NameStr(typtuple->typname))); ReleaseSysCache(tuple); } } return result.data; }
static const char * map_sql_type_to_xmlschema_type | ( | Oid | typeoid, | |
int | typmod | |||
) | [static] |
Definition at line 3363 of file xml.c.
References appendStringInfo(), BOOLOID, BPCHAROID, BYTEAOID, StringInfoData::data, DATEOID, FLOAT4OID, FLOAT8OID, get_typtype(), getBaseTypeAndTypmod(), initStringInfo(), INT2OID, INT4OID, INT8OID, map_sql_type_to_xml_name(), NUMERICOID, TEXTOID, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, TYPTYPE_DOMAIN, VARCHAROID, VARHDRSZ, xmlbinary, XMLBINARY_BASE64, and XMLOID.
Referenced by map_sql_typecoll_to_xmlschema_types().
{ StringInfoData result; const char *typename = map_sql_type_to_xml_name(typeoid, typmod); initStringInfo(&result); if (typeoid == XMLOID) { appendStringInfo(&result, "<xsd:complexType mixed=\"true\">\n" " <xsd:sequence>\n" " <xsd:any name=\"element\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"skip\"/>\n" " </xsd:sequence>\n" "</xsd:complexType>\n"); } else { appendStringInfo(&result, "<xsd:simpleType name=\"%s\">\n", typename); switch (typeoid) { case BPCHAROID: case VARCHAROID: case TEXTOID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:string\">\n"); if (typmod != -1) appendStringInfo(&result, " <xsd:maxLength value=\"%d\"/>\n", typmod - VARHDRSZ); appendStringInfo(&result, " </xsd:restriction>\n"); break; case BYTEAOID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:%s\">\n" " </xsd:restriction>\n", xmlbinary == XMLBINARY_BASE64 ? "base64Binary" : "hexBinary"); break; case NUMERICOID: if (typmod != -1) appendStringInfo(&result, " <xsd:restriction base=\"xsd:decimal\">\n" " <xsd:totalDigits value=\"%d\"/>\n" " <xsd:fractionDigits value=\"%d\"/>\n" " </xsd:restriction>\n", ((typmod - VARHDRSZ) >> 16) & 0xffff, (typmod - VARHDRSZ) & 0xffff); break; case INT2OID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:short\">\n" " <xsd:maxInclusive value=\"%d\"/>\n" " <xsd:minInclusive value=\"%d\"/>\n" " </xsd:restriction>\n", SHRT_MAX, SHRT_MIN); break; case INT4OID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:int\">\n" " <xsd:maxInclusive value=\"%d\"/>\n" " <xsd:minInclusive value=\"%d\"/>\n" " </xsd:restriction>\n", INT_MAX, INT_MIN); break; case INT8OID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:long\">\n" " <xsd:maxInclusive value=\"" INT64_FORMAT "\"/>\n" " <xsd:minInclusive value=\"" INT64_FORMAT "\"/>\n" " </xsd:restriction>\n", (((uint64) 1) << (sizeof(int64) * 8 - 1)) - 1, (((uint64) 1) << (sizeof(int64) * 8 - 1))); break; case FLOAT4OID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:float\"></xsd:restriction>\n"); break; case FLOAT8OID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:double\"></xsd:restriction>\n"); break; case BOOLOID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:boolean\"></xsd:restriction>\n"); break; case TIMEOID: case TIMETZOID: { const char *tz = (typeoid == TIMETZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : ""); if (typmod == -1) appendStringInfo(&result, " <xsd:restriction base=\"xsd:time\">\n" " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n" " </xsd:restriction>\n", tz); else if (typmod == 0) appendStringInfo(&result, " <xsd:restriction base=\"xsd:time\">\n" " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n" " </xsd:restriction>\n", tz); else appendStringInfo(&result, " <xsd:restriction base=\"xsd:time\">\n" " <xsd:pattern value=\"\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n" " </xsd:restriction>\n", typmod - VARHDRSZ, tz); break; } case TIMESTAMPOID: case TIMESTAMPTZOID: { const char *tz = (typeoid == TIMESTAMPTZOID ? "(+|-)\\p{Nd}{2}:\\p{Nd}{2}" : ""); if (typmod == -1) appendStringInfo(&result, " <xsd:restriction base=\"xsd:dateTime\">\n" " <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" " </xsd:restriction>\n", tz); else if (typmod == 0) appendStringInfo(&result, " <xsd:restriction base=\"xsd:dateTime\">\n" " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n" " </xsd:restriction>\n", tz); else appendStringInfo(&result, " <xsd:restriction base=\"xsd:dateTime\">\n" " <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" " </xsd:restriction>\n", typmod - VARHDRSZ, tz); break; } case DATEOID: appendStringInfo(&result, " <xsd:restriction base=\"xsd:date\">\n" " <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}\"/>\n" " </xsd:restriction>\n"); break; default: if (get_typtype(typeoid) == TYPTYPE_DOMAIN) { Oid base_typeoid; int32 base_typmod = -1; base_typeoid = getBaseTypeAndTypmod(typeoid, &base_typmod); appendStringInfo(&result, " <xsd:restriction base=\"%s\"/>\n", map_sql_type_to_xml_name(base_typeoid, base_typmod)); } break; } appendStringInfo(&result, "</xsd:simpleType>\n"); } return result.data; }
static const char * map_sql_typecoll_to_xmlschema_types | ( | List * | tupdesc_list | ) | [static] |
Definition at line 3309 of file xml.c.
References appendStringInfo(), tupleDesc::attrs, StringInfoData::data, getBaseType(), i, initStringInfo(), lfirst, lfirst_oid, list_append_unique_oid(), map_sql_type_to_xmlschema_type(), and tupleDesc::natts.
Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().
{ List *uniquetypes = NIL; int i; StringInfoData result; ListCell *cell0; /* extract all column types used in the set of TupleDescs */ foreach(cell0, tupdesc_list) { TupleDesc tupdesc = (TupleDesc) lfirst(cell0); for (i = 0; i < tupdesc->natts; i++) { if (tupdesc->attrs[i]->attisdropped) continue; uniquetypes = list_append_unique_oid(uniquetypes, tupdesc->attrs[i]->atttypid); } } /* add base types of domains */ foreach(cell0, uniquetypes) { Oid typid = lfirst_oid(cell0); Oid basetypid = getBaseType(typid); if (basetypid != typid) uniquetypes = list_append_unique_oid(uniquetypes, basetypid); } /* Convert to textual form */ initStringInfo(&result); foreach(cell0, uniquetypes) { appendStringInfo(&result, "%s\n", map_sql_type_to_xmlschema_type(lfirst_oid(cell0), -1)); } return result.data; }
Definition at line 1956 of file xml.c.
References appendStringInfoString(), ARR_ELEMTYPE, BOOLOID, BYTEAOID, StringInfoData::data, DATE_NOT_FINITE, DATEOID, 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, NULL, 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(), timestamp2tm(), TIMESTAMP_NOT_FINITE, TIMESTAMPOID, TIMESTAMPTZOID, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, type_is_array_domain, USE_XSD_DATES, VARDATA_ANY, VARSIZE_ANY_EXHDR, xml_ereport(), xmlbinary, XMLBINARY_BASE64, and XMLOID.
Referenced by ExecEvalXml(), map_sql_value_to_xml_value(), SPI_sql_row_to_xmlelement(), and xmlelement().
{ if (type_is_array_domain(type)) { ArrayType *array; Oid elmtype; int16 elmlen; bool elmbyval; char elmalign; int num_elems; Datum *elem_values; bool *elem_nulls; StringInfoData buf; int i; array = DatumGetArrayTypeP(value); elmtype = ARR_ELEMTYPE(array); get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign); deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, &elem_values, &elem_nulls, &num_elems); initStringInfo(&buf); for (i = 0; i < num_elems; i++) { if (elem_nulls[i]) continue; appendStringInfoString(&buf, "<element>"); appendStringInfoString(&buf, map_sql_value_to_xml_value(elem_values[i], elmtype, true)); appendStringInfoString(&buf, "</element>"); } pfree(elem_values); pfree(elem_nulls); return buf.data; } else { Oid typeOut; bool isvarlena; char *str; /* * Flatten domains; the special-case treatments below should apply * to, eg, domains over boolean not just boolean. */ type = getBaseType(type); /* * Special XSD formatting for some data types */ switch (type) { case BOOLOID: if (DatumGetBool(value)) return "true"; else return "false"; case DATEOID: { DateADT date; struct pg_tm tm; char buf[MAXDATELEN + 1]; date = DatumGetDateADT(value); /* XSD doesn't support infinite values */ if (DATE_NOT_FINITE(date)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("date out of range"), errdetail("XML does not support infinite date values."))); j2date(date + POSTGRES_EPOCH_JDATE, &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday)); EncodeDateOnly(&tm, USE_XSD_DATES, buf); return pstrdup(buf); } case TIMESTAMPOID: { Timestamp timestamp; struct pg_tm tm; fsec_t fsec; char buf[MAXDATELEN + 1]; timestamp = DatumGetTimestamp(value); /* XSD doesn't support infinite values */ if (TIMESTAMP_NOT_FINITE(timestamp)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"), errdetail("XML does not support infinite timestamp values."))); else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0) EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf); else ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); return pstrdup(buf); } case TIMESTAMPTZOID: { TimestampTz timestamp; struct pg_tm tm; int tz; fsec_t fsec; const char *tzn = NULL; char buf[MAXDATELEN + 1]; timestamp = DatumGetTimestamp(value); /* XSD doesn't support infinite values */ if (TIMESTAMP_NOT_FINITE(timestamp)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"), errdetail("XML does not support infinite timestamp values."))); else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0) EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf); else ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); return pstrdup(buf); } #ifdef USE_LIBXML case BYTEAOID: { bytea *bstr = DatumGetByteaPP(value); PgXmlErrorContext *xmlerrcxt; volatile xmlBufferPtr buf = NULL; volatile xmlTextWriterPtr writer = NULL; char *result; xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL); PG_TRY(); { buf = xmlBufferCreate(); if (buf == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate xmlBuffer"); writer = xmlNewTextWriterMemory(buf, 0); if (writer == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate xmlTextWriter"); if (xmlbinary == XMLBINARY_BASE64) xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr), 0, VARSIZE_ANY_EXHDR(bstr)); else xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr), 0, VARSIZE_ANY_EXHDR(bstr)); /* we MUST do this now to flush data out to the buffer */ xmlFreeTextWriter(writer); writer = NULL; result = pstrdup((const char *) xmlBufferContent(buf)); } PG_CATCH(); { if (writer) xmlFreeTextWriter(writer); if (buf) xmlBufferFree(buf); pg_xml_done(xmlerrcxt, true); PG_RE_THROW(); } PG_END_TRY(); xmlBufferFree(buf); pg_xml_done(xmlerrcxt, false); return result; } #endif /* USE_LIBXML */ } /* * otherwise, just use the type's native text representation */ getTypeOutputInfo(type, &typeOut, &isvarlena); str = OidOutputFunctionCall(typeOut, value); /* ... exactly as-is for XML, and when escaping is not wanted */ if (type == XMLOID || !xml_escape_strings) return str; /* otherwise, translate special characters as needed */ return escape_xml(str); } }
char* map_xml_name_to_sql_identifier | ( | char * | name | ) |
Definition at line 1916 of file xml.c.
References appendBinaryStringInfo(), appendStringInfoString(), StringInfoData::data, initStringInfo(), pg_mblen(), and unicode_to_sqlchar().
Referenced by get_rule_expr().
{ StringInfoData buf; char *p; initStringInfo(&buf); for (p = name; *p; p += pg_mblen(p)) { if (*p == '_' && *(p + 1) == 'x' && isxdigit((unsigned char) *(p + 2)) && isxdigit((unsigned char) *(p + 3)) && isxdigit((unsigned char) *(p + 4)) && isxdigit((unsigned char) *(p + 5)) && *(p + 6) == '_') { unsigned int u; sscanf(p + 2, "%X", &u); appendStringInfoString(&buf, unicode_to_sqlchar(u)); p += 6; } else appendBinaryStringInfo(&buf, p, pg_mblen(p)); } return buf.data; }
static List* query_to_oid_list | ( | const char * | query | ) | [static] |
Definition at line 2264 of file xml.c.
References DatumGetObjectId, i, lappend_oid(), sort-test::list, SPI_execute(), SPI_getbinval(), SPI_processed, SPI_tuptable, SPITupleTable::tupdesc, and SPITupleTable::vals.
Referenced by database_get_xml_visible_schemas(), database_get_xml_visible_tables(), and schema_get_xml_visible_tables().
{ int i; List *list = NIL; SPI_execute(query, true, 0); for (i = 0; i < SPI_processed; i++) { Datum oid; bool isnull; oid = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull); if (!isnull) list = lappend_oid(list, DatumGetObjectId(oid)); } return list; }
Datum query_to_xml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2361 of file xml.c.
References NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, query_to_xml_internal(), stringinfo_to_xmltype(), and text_to_cstring().
{ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0)); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); PG_RETURN_XML_P(stringinfo_to_xmltype(query_to_xml_internal(query, NULL, NULL, nulls, tableforest, targetns, true))); }
Datum query_to_xml_and_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2594 of file xml.c.
References _SPI_strdup(), elog, ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, query_to_xml_internal(), SPI_connect(), SPI_cursor_close(), SPI_cursor_open(), SPI_finish(), SPI_prepare(), stringinfo_to_xmltype(), text_to_cstring(), and PortalData::tupDesc.
{ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0)); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); const char *xmlschema; SPIPlanPtr plan; Portal portal; SPI_connect(); if ((plan = SPI_prepare(query, 0, NULL)) == NULL) elog(ERROR, "SPI_prepare(\"%s\") failed", query); if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL) elog(ERROR, "SPI_cursor_open(\"%s\") failed", query); xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc, InvalidOid, nulls, tableforest, targetns)); SPI_cursor_close(portal); SPI_finish(); PG_RETURN_XML_P(stringinfo_to_xmltype(query_to_xml_internal(query, NULL, xmlschema, nulls, tableforest, targetns, true))); }
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 2454 of file xml.c.
References appendStringInfo(), appendStringInfoString(), 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().
{ StringInfo result; char *xmltn; int i; if (tablename) xmltn = map_sql_identifier_to_xml_name(tablename, true, false); else xmltn = "table"; result = makeStringInfo(); SPI_connect(); if (SPI_execute(query, true, 0) != SPI_OK_SELECT) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("invalid query"))); if (!tableforest) { xmldata_root_element_start(result, xmltn, xmlschema, targetns, top_level); appendStringInfoString(result, "\n"); } if (xmlschema) appendStringInfo(result, "%s\n\n", xmlschema); for (i = 0; i < SPI_processed; i++) SPI_sql_row_to_xmlelement(i, result, tablename, nulls, tableforest, targetns, top_level); if (!tableforest) xmldata_root_element_end(result, xmltn); SPI_finish(); return result; }
Datum query_to_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2518 of file xml.c.
References _SPI_strdup(), cstring_to_xmltype(), elog, ERROR, InvalidOid, map_sql_table_to_xmlschema(), NULL, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, SPI_connect(), SPI_cursor_close(), SPI_cursor_open(), SPI_finish(), SPI_prepare(), text_to_cstring(), and PortalData::tupDesc.
{ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0)); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); const char *result; SPIPlanPtr plan; Portal portal; SPI_connect(); if ((plan = SPI_prepare(query, 0, NULL)) == NULL) elog(ERROR, "SPI_prepare(\"%s\") failed", query); if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL) elog(ERROR, "SPI_cursor_open(\"%s\") failed", query); result = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc, InvalidOid, nulls, tableforest, targetns)); SPI_cursor_close(portal); SPI_finish(); PG_RETURN_XML_P(cstring_to_xmltype(result)); }
Definition at line 2289 of file xml.c.
References appendStringInfo(), StringInfoData::data, initStringInfo(), and query_to_oid_list().
Referenced by schema_to_xml_internal(), and schema_to_xmlschema_internal().
{ StringInfoData query; initStringInfo(&query); appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class WHERE relnamespace = %u AND relkind IN ('r', 'm', 'v') AND pg_catalog.has_table_privilege (oid, 'SELECT') ORDER BY relname;", nspid); return query_to_oid_list(query.data); }
Datum schema_to_xml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2676 of file xml.c.
References LookupExplicitNamespace(), NameStr, NULL, 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().
{ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); char *schemaname; Oid nspid; schemaname = NameStr(*name); nspid = LookupExplicitNamespace(schemaname, false); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, true))); }
Datum schema_to_xml_and_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2780 of file xml.c.
References StringInfoData::data, LookupExplicitNamespace(), NameStr, PG_GETARG_BOOL, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, schema_to_xml_internal(), schema_to_xmlschema_internal(), stringinfo_to_xmltype(), and text_to_cstring().
{ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); char *schemaname; Oid nspid; StringInfo xmlschema; schemaname = NameStr(*name); nspid = LookupExplicitNamespace(schemaname, false); xmlschema = schema_to_xmlschema_internal(schemaname, nulls, tableforest, targetns); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, xmlschema->data, nulls, tableforest, targetns, true))); }
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 2630 of file xml.c.
References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, get_namespace_name(), lfirst_oid, makeStringInfo(), map_sql_identifier_to_xml_name(), NULL, schema_get_xml_visible_tables(), SPI_connect(), SPI_finish(), SPI_pop(), SPI_push(), 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().
{ StringInfo result; char *xmlsn; List *relid_list; ListCell *cell; xmlsn = map_sql_identifier_to_xml_name(get_namespace_name(nspid), true, false); result = makeStringInfo(); xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level); appendStringInfoString(result, "\n"); if (xmlschema) appendStringInfo(result, "%s\n\n", xmlschema); SPI_connect(); relid_list = schema_get_xml_visible_tables(nspid); SPI_push(); foreach(cell, relid_list) { Oid relid = lfirst_oid(cell); StringInfo subres; subres = table_to_xml_internal(relid, NULL, nulls, tableforest, targetns, false); appendStringInfoString(result, subres->data); appendStringInfoChar(result, '\n'); } SPI_pop(); SPI_finish(); xmldata_root_element_end(result, xmlsn); return result; }
Datum schema_to_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2767 of file xml.c.
References 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().
{ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xmlschema_internal(NameStr(*name), nulls, tableforest, targetns))); }
static StringInfo schema_to_xmlschema_internal | ( | const char * | schemaname, | |
bool | nulls, | |||
bool | tableforest, | |||
const char * | targetns | |||
) | [static] |
Definition at line 2722 of file xml.c.
References AccessShareLock, appendStringInfoString(), CreateTupleDescCopy(), heap_close, heap_open(), lappend(), lfirst_oid, LookupExplicitNamespace(), makeStringInfo(), map_sql_schema_to_xmlschema_types(), map_sql_typecoll_to_xmlschema_types(), NoLock, RelationData::rd_att, schema_get_xml_visible_tables(), SPI_connect(), SPI_finish(), xsd_schema_element_end(), and xsd_schema_element_start().
Referenced by schema_to_xml_and_xmlschema(), and schema_to_xmlschema().
{ Oid nspid; List *relid_list; List *tupdesc_list; ListCell *cell; StringInfo result; result = makeStringInfo(); nspid = LookupExplicitNamespace(schemaname, false); xsd_schema_element_start(result, targetns); SPI_connect(); relid_list = schema_get_xml_visible_tables(nspid); tupdesc_list = NIL; foreach(cell, relid_list) { Relation rel; rel = heap_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); heap_close(rel, NoLock); } appendStringInfoString(result, map_sql_typecoll_to_xmlschema_types(tupdesc_list)); appendStringInfoString(result, map_sql_schema_to_xmlschema_types(nspid, relid_list, nulls, tableforest, targetns)); xsd_schema_element_end(result); SPI_finish(); return result; }
static void SPI_sql_row_to_xmlelement | ( | int | rownum, | |
StringInfo | result, | |||
char * | tablename, | |||
bool | nulls, | |||
bool | tableforest, | |||
const char * | targetns, | |||
bool | top_level | |||
) | [static] |
Definition at line 3540 of file xml.c.
References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), i, map_sql_identifier_to_xml_name(), map_sql_value_to_xml_value(), tupleDesc::natts, NULL, 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().
{ int i; char *xmltn; if (tablename) xmltn = map_sql_identifier_to_xml_name(tablename, true, false); else { if (tableforest) xmltn = "row"; else xmltn = "table"; } if (tableforest) xmldata_root_element_start(result, xmltn, NULL, targetns, top_level); else appendStringInfoString(result, "<row>\n"); for (i = 1; i <= SPI_tuptable->tupdesc->natts; i++) { char *colname; Datum colval; bool isnull; colname = map_sql_identifier_to_xml_name(SPI_fname(SPI_tuptable->tupdesc, i), true, false); colval = SPI_getbinval(SPI_tuptable->vals[rownum], SPI_tuptable->tupdesc, i, &isnull); if (isnull) { if (nulls) appendStringInfo(result, " <%s xsi:nil=\"true\"/>\n", colname); } else appendStringInfo(result, " <%s>%s</%s>\n", colname, map_sql_value_to_xml_value(colval, SPI_gettypeid(SPI_tuptable->tupdesc, i), true), colname); } if (tableforest) { xmldata_root_element_end(result, xmltn); appendStringInfoChar(result, '\n'); } else appendStringInfoString(result, "</row>\n\n"); }
static xmltype* stringinfo_to_xmltype | ( | StringInfo | buf | ) | [static] |
Definition at line 398 of file xml.c.
References cstring_to_text_with_len(), StringInfoData::data, and StringInfoData::len.
Referenced by cursor_to_xml(), database_to_xml(), database_to_xml_and_xmlschema(), database_to_xmlschema(), query_to_xml(), query_to_xml_and_xmlschema(), schema_to_xml(), schema_to_xml_and_xmlschema(), schema_to_xmlschema(), table_to_xml(), table_to_xml_and_xmlschema(), xmlcomment(), xmlconcat(), xmlpi(), and xmlroot().
{ return (xmltype *) cstring_to_text_with_len(buf->data, buf->len); }
Datum table_to_xml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2347 of file xml.c.
References NULL, 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().
{ Oid relid = PG_GETARG_OID(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); PG_RETURN_XML_P(stringinfo_to_xmltype(table_to_xml_internal(relid, NULL, nulls, tableforest, targetns, true))); }
Datum table_to_xml_and_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2573 of file xml.c.
References AccessShareLock, heap_close, heap_open(), 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_to_xml_internal(), and text_to_cstring().
{ Oid relid = PG_GETARG_OID(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); Relation rel; const char *xmlschema; rel = heap_open(relid, AccessShareLock); xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls, tableforest, targetns); heap_close(rel, NoLock); PG_RETURN_XML_P(stringinfo_to_xmltype(table_to_xml_internal(relid, xmlschema, nulls, tableforest, targetns, true))); }
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 2330 of file xml.c.
References appendStringInfo(), StringInfoData::data, DatumGetCString, DirectFunctionCall1, get_rel_name(), initStringInfo(), ObjectIdGetDatum, query_to_xml_internal(), and regclassout().
Referenced by schema_to_xml_internal(), table_to_xml(), and table_to_xml_and_xmlschema().
{ StringInfoData query; initStringInfo(&query); appendStringInfo(&query, "SELECT * FROM %s", DatumGetCString(DirectFunctionCall1(regclassout, ObjectIdGetDatum(relid)))); return query_to_xml_internal(query.data, get_rel_name(relid), xmlschema, nulls, tableforest, targetns, top_level); }
Datum table_to_xmlschema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 2499 of file xml.c.
References AccessShareLock, cstring_to_xmltype(), heap_close, heap_open(), map_sql_table_to_xmlschema(), NoLock, PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_XML_P, RelationData::rd_att, and text_to_cstring().
{ Oid relid = PG_GETARG_OID(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3)); const char *result; Relation rel; rel = heap_open(relid, AccessShareLock); result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls, tableforest, targetns); heap_close(rel, NoLock); PG_RETURN_XML_P(cstring_to_xmltype(result)); }
Datum texttoxml | ( | PG_FUNCTION_ARGS | ) |
Definition at line 547 of file xml.c.
References PG_GETARG_TEXT_P, PG_RETURN_XML_P, xmloption, and xmlparse().
{ text *data = PG_GETARG_TEXT_P(0); PG_RETURN_XML_P(xmlparse(data, xmloption, true)); }
static char* unicode_to_sqlchar | ( | pg_wchar | c | ) | [static] |
Definition at line 1892 of file xml.c.
References GetDatabaseEncoding(), pg_do_encoding_conversion(), pg_encoding_mblen(), PG_UTF8, pstrdup(), and unicode_to_utf8().
Referenced by map_xml_name_to_sql_identifier().
{ unsigned char utf8string[5]; /* need room for trailing zero */ char *result; memset(utf8string, 0, sizeof(utf8string)); unicode_to_utf8(c, utf8string); result = (char *) pg_do_encoding_conversion(utf8string, pg_encoding_mblen(PG_UTF8, (char *) utf8string), PG_UTF8, GetDatabaseEncoding()); /* if pg_do_encoding_conversion didn't strdup, we must */ if (result == (char *) utf8string) result = pstrdup(result); return result; }
Datum xml_in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 206 of file xml.c.
References cstring_to_text(), GetDatabaseEncoding(), NO_XML_SUPPORT, PG_GETARG_CSTRING, PG_RETURN_XML_P, and xmloption.
{ #ifdef USE_LIBXML char *s = PG_GETARG_CSTRING(0); xmltype *vardata; xmlDocPtr doc; vardata = (xmltype *) cstring_to_text(s); /* * Parse the data to check if it is well-formed XML data. Assume that * ERROR occurred if parsing failed. */ doc = xml_parse(vardata, xmloption, true, GetDatabaseEncoding()); xmlFreeDoc(doc); PG_RETURN_XML_P(vardata); #else NO_XML_SUPPORT(); return 0; #endif }
Definition at line 839 of file xml.c.
References CopyErrorData(), CurrentMemoryContext, FlushErrorState(), GetDatabaseEncoding(), MemoryContextSwitchTo(), NO_XML_SUPPORT, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, ErrorData::sqlerrcode, and XMLOPTION_DOCUMENT.
Referenced by ExecEvalXml(), and xmltotext_with_xmloption().
{ #ifdef USE_LIBXML bool result; volatile xmlDocPtr doc = NULL; MemoryContext ccxt = CurrentMemoryContext; /* We want to catch ereport(INVALID_XML_DOCUMENT) and return false */ PG_TRY(); { doc = xml_parse((text *) arg, XMLOPTION_DOCUMENT, true, GetDatabaseEncoding()); result = true; } PG_CATCH(); { ErrorData *errdata; MemoryContext ecxt; ecxt = MemoryContextSwitchTo(ccxt); errdata = CopyErrorData(); if (errdata->sqlerrcode == ERRCODE_INVALID_XML_DOCUMENT) { FlushErrorState(); result = false; } else { MemoryContextSwitchTo(ecxt); PG_RE_THROW(); } } PG_END_TRY(); if (doc) xmlFreeDoc(doc); return result; #else /* not USE_LIBXML */ NO_XML_SUPPORT(); return false; #endif /* not USE_LIBXML */ }
Datum xml_is_well_formed | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4036 of file xml.c.
References NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_GETARG_TEXT_P, PG_RE_THROW, PG_RETURN_BOOL, PG_TRY, pg_xml_done(), PG_XML_STRICTNESS_LEGACY, pgxml_parser_init(), VARDATA, VARSIZE, and xmloption.
{ #ifdef USE_LIBXML text *data = PG_GETARG_TEXT_P(0); PG_RETURN_BOOL(wellformed_xml(data, xmloption)); #else NO_XML_SUPPORT(); return 0; #endif /* not USE_LIBXML */ }
Datum xml_is_well_formed_content | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4062 of file xml.c.
References NO_XML_SUPPORT, PG_GETARG_TEXT_P, PG_RETURN_BOOL, and XMLOPTION_CONTENT.
{ #ifdef USE_LIBXML text *data = PG_GETARG_TEXT_P(0); PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_CONTENT)); #else NO_XML_SUPPORT(); return 0; #endif /* not USE_LIBXML */ }
Datum xml_is_well_formed_document | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4049 of file xml.c.
References NO_XML_SUPPORT, PG_GETARG_TEXT_P, PG_RETURN_BOOL, and XMLOPTION_DOCUMENT.
{ #ifdef USE_LIBXML text *data = PG_GETARG_TEXT_P(0); PG_RETURN_BOOL(wellformed_xml(data, XMLOPTION_DOCUMENT)); #else NO_XML_SUPPORT(); return 0; #endif /* not USE_LIBXML */ }
Datum xml_out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 284 of file xml.c.
References PG_GETARG_XML_P, PG_RETURN_CSTRING, and xml_out_internal().
{ xmltype *x = PG_GETARG_XML_P(0); /* * xml_out removes the encoding property in all cases. This is because we * cannot control from here whether the datum will be converted to a * different client encoding, so we'd do more harm than good by including * it. */ PG_RETURN_CSTRING(xml_out_internal(x, 0)); }
Definition at line 241 of file xml.c.
References appendStringInfoString(), buf, StringInfoData::data, initStringInfo(), NULL, pfree(), text_to_cstring(), and WARNING.
Referenced by xml_out(), and xml_send().
{ char *str = text_to_cstring((text *) x); #ifdef USE_LIBXML size_t len = strlen(str); xmlChar *version; int standalone; int res_code; if ((res_code = parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone)) == 0) { StringInfoData buf; initStringInfo(&buf); if (!print_xml_decl(&buf, version, target_encoding, standalone)) { /* * If we are not going to produce an XML declaration, eat a single * newline in the original string to prevent empty first lines in * the output. */ if (*(str + len) == '\n') len += 1; } appendStringInfoString(&buf, str + len); pfree(str); return buf.data; } xml_ereport_by_code(WARNING, ERRCODE_INTERNAL_ERROR, "could not parse XML declaration in stored value", res_code); #endif return str; }
Datum xml_recv | ( | PG_FUNCTION_ARGS | ) |
Definition at line 299 of file xml.c.
References buf, cstring_to_text(), StringInfoData::cursor, encoding, GetDatabaseEncoding(), StringInfoData::len, NO_XML_SUPPORT, NULL, palloc(), pfree(), pg_do_encoding_conversion(), PG_GETARG_POINTER, PG_RETURN_XML_P, pq_getmsgbytes(), SET_VARSIZE, VARDATA, VARHDRSZ, and xmloption.
{ #ifdef USE_LIBXML StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); xmltype *result; char *str; char *newstr; int nbytes; xmlDocPtr doc; xmlChar *encodingStr = NULL; int encoding; /* * Read the data in raw format. We don't know yet what the encoding is, as * that information is embedded in the xml declaration; so we have to * parse that before converting to server encoding. */ nbytes = buf->len - buf->cursor; str = (char *) pq_getmsgbytes(buf, nbytes); /* * We need a null-terminated string to pass to parse_xml_decl(). Rather * than make a separate copy, make the temporary result one byte bigger * than it needs to be. */ result = palloc(nbytes + 1 + VARHDRSZ); SET_VARSIZE(result, nbytes + VARHDRSZ); memcpy(VARDATA(result), str, nbytes); str = VARDATA(result); str[nbytes] = '\0'; parse_xml_decl((const xmlChar *) str, NULL, NULL, &encodingStr, NULL); /* * If encoding wasn't explicitly specified in the XML header, treat it as * UTF-8, as that's the default in XML. This is different from xml_in(), * where the input has to go through the normal client to server encoding * conversion. */ encoding = encodingStr ? xmlChar_to_encoding(encodingStr) : PG_UTF8; /* * Parse the data to check if it is well-formed XML data. Assume that * xml_parse will throw ERROR if not. */ doc = xml_parse(result, xmloption, true, encoding); xmlFreeDoc(doc); /* Now that we know what we're dealing with, convert to server encoding */ newstr = (char *) pg_do_encoding_conversion((unsigned char *) str, nbytes, encoding, GetDatabaseEncoding()); if (newstr != str) { pfree(result); result = (xmltype *) cstring_to_text(newstr); pfree(newstr); } PG_RETURN_XML_P(result); #else NO_XML_SUPPORT(); return 0; #endif }
Datum xml_send | ( | PG_FUNCTION_ARGS | ) |
Definition at line 369 of file xml.c.
References buf, pfree(), pg_get_client_encoding(), PG_GETARG_XML_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), and xml_out_internal().
{ xmltype *x = PG_GETARG_XML_P(0); char *outval; StringInfoData buf; /* * xml_out_internal doesn't convert the encoding, it just prints the right * declaration. pq_sendtext will do the conversion. */ outval = xml_out_internal(x, pg_get_client_encoding()); pq_begintypsend(&buf); pq_sendtext(&buf, outval, strlen(outval)); pfree(outval); PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); }
Datum xmlcomment | ( | PG_FUNCTION_ARGS | ) |
Definition at line 422 of file xml.c.
References appendStringInfo(), appendStringInfoText(), arg, ereport, errcode(), errmsg(), ERROR, i, initStringInfo(), NO_XML_SUPPORT, PG_GETARG_TEXT_P, PG_RETURN_XML_P, stringinfo_to_xmltype(), VARDATA, and VARSIZE.
{ #ifdef USE_LIBXML text *arg = PG_GETARG_TEXT_P(0); char *argdata = VARDATA(arg); int len = VARSIZE(arg) - VARHDRSZ; StringInfoData buf; int i; /* check for "--" in string or "-" at the end */ for (i = 1; i < len; i++) { if (argdata[i] == '-' && argdata[i - 1] == '-') ereport(ERROR, (errcode(ERRCODE_INVALID_XML_COMMENT), errmsg("invalid XML comment"))); } if (len > 0 && argdata[len - 1] == '-') ereport(ERROR, (errcode(ERRCODE_INVALID_XML_COMMENT), errmsg("invalid XML comment"))); initStringInfo(&buf); appendStringInfo(&buf, "<!--"); appendStringInfoText(&buf, arg); appendStringInfo(&buf, "-->"); PG_RETURN_XML_P(stringinfo_to_xmltype(&buf)); #else NO_XML_SUPPORT(); return 0; #endif }
Definition at line 463 of file xml.c.
References appendStringInfoString(), StringInfoData::data, DatumGetXmlP, initStringInfo(), lfirst, NO_XML_SUPPORT, NULL, pfree(), PointerGetDatum, stringinfo_to_xmltype(), text_to_cstring(), and VARSIZE.
Referenced by ExecEvalXml(), and xmlconcat2().
{ #ifdef USE_LIBXML int global_standalone = 1; xmlChar *global_version = NULL; bool global_version_no_value = false; StringInfoData buf; ListCell *v; initStringInfo(&buf); foreach(v, args) { xmltype *x = DatumGetXmlP(PointerGetDatum(lfirst(v))); size_t len; xmlChar *version; int standalone; char *str; len = VARSIZE(x) - VARHDRSZ; str = text_to_cstring((text *) x); parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone); if (standalone == 0 && global_standalone == 1) global_standalone = 0; if (standalone < 0) global_standalone = -1; if (!version) global_version_no_value = true; else if (!global_version) global_version = version; else if (xmlStrcmp(version, global_version) != 0) global_version_no_value = true; appendStringInfoString(&buf, str + len); pfree(str); } if (!global_version_no_value || global_standalone >= 0) { StringInfoData buf2; initStringInfo(&buf2); print_xml_decl(&buf2, (!global_version_no_value) ? global_version : NULL, 0, global_standalone); appendStringInfoString(&buf2, buf.data); buf = buf2; } return stringinfo_to_xmltype(&buf); #else NO_XML_SUPPORT(); return NULL; #endif }
Datum xmlconcat2 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 529 of file xml.c.
References list_make2, PG_ARGISNULL, PG_GETARG_XML_P, PG_RETURN_NULL, PG_RETURN_XML_P, and xmlconcat().
{ if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); else PG_RETURN_XML_P(PG_GETARG_XML_P(1)); } else if (PG_ARGISNULL(1)) PG_RETURN_XML_P(PG_GETARG_XML_P(0)); else PG_RETURN_XML_P(xmlconcat(list_make2(PG_GETARG_XML_P(0), PG_GETARG_XML_P(1)))); }
static void xmldata_root_element_end | ( | StringInfo | result, | |
const char * | eltname | |||
) | [static] |
Definition at line 2447 of file xml.c.
References appendStringInfo().
Referenced by database_to_xml_internal(), query_to_xml_internal(), schema_to_xml_internal(), and SPI_sql_row_to_xmlelement().
{ appendStringInfo(result, "</%s>\n", eltname); }
static void xmldata_root_element_start | ( | StringInfo | result, | |
const char * | eltname, | |||
const char * | xmlschema, | |||
const char * | targetns, | |||
bool | top_level | |||
) | [static] |
Definition at line 2420 of file xml.c.
References appendStringInfo(), appendStringInfoString(), Assert, and NAMESPACE_XSI.
Referenced by database_to_xml_internal(), query_to_xml_internal(), schema_to_xml_internal(), and SPI_sql_row_to_xmlelement().
{ /* This isn't really wrong but currently makes no sense. */ Assert(top_level || !xmlschema); appendStringInfo(result, "<%s", eltname); if (top_level) { appendStringInfoString(result, " xmlns:xsi=\"" NAMESPACE_XSI "\""); if (strlen(targetns) > 0) appendStringInfo(result, " xmlns=\"%s\"", targetns); } if (xmlschema) { /* FIXME: better targets */ if (strlen(targetns) > 0) appendStringInfo(result, " xsi:schemaLocation=\"%s #\"", targetns); else appendStringInfo(result, " xsi:noNamespaceSchemaLocation=\"#\""); } appendStringInfo(result, ">\n"); }
xmltype* xmlelement | ( | XmlExprState * | xmlExpr, | |
ExprContext * | econtext | |||
) |
Definition at line 579 of file xml.c.
References arg, XmlExpr::arg_names, XmlExprState::args, ERROR, ExecEvalExpr, ExprState::expr, exprType(), forboth, i, lappend(), lfirst, map_sql_value_to_xml_value(), XmlExpr::name, XmlExprState::named_args, NIL, NO_XML_SUPPORT, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pg_xml_done(), pg_xml_init(), PG_XML_STRICTNESS_ALL, strVal, value, xml_ereport(), and XmlExprState::xprstate.
Referenced by ExecEvalXml().
{ #ifdef USE_LIBXML XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr; xmltype *result; List *named_arg_strings; List *arg_strings; int i; ListCell *arg; ListCell *narg; PgXmlErrorContext *xmlerrcxt; volatile xmlBufferPtr buf = NULL; volatile xmlTextWriterPtr writer = NULL; /* * We first evaluate all the arguments, then start up libxml and create * the result. This avoids issues if one of the arguments involves a call * to some other function or subsystem that wants to use libxml on its own * terms. */ named_arg_strings = NIL; i = 0; foreach(arg, xmlExpr->named_args) { ExprState *e = (ExprState *) lfirst(arg); Datum value; bool isnull; char *str; value = ExecEvalExpr(e, econtext, &isnull, NULL); if (isnull) str = NULL; else str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr), false); named_arg_strings = lappend(named_arg_strings, str); i++; } arg_strings = NIL; foreach(arg, xmlExpr->args) { ExprState *e = (ExprState *) lfirst(arg); Datum value; bool isnull; char *str; value = ExecEvalExpr(e, econtext, &isnull, NULL); /* here we can just forget NULL elements immediately */ if (!isnull) { str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true); arg_strings = lappend(arg_strings, str); } } /* now safe to run libxml */ xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL); PG_TRY(); { buf = xmlBufferCreate(); if (buf == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate xmlBuffer"); writer = xmlNewTextWriterMemory(buf, 0); if (writer == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate xmlTextWriter"); xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name); forboth(arg, named_arg_strings, narg, xexpr->arg_names) { char *str = (char *) lfirst(arg); char *argname = strVal(lfirst(narg)); if (str) xmlTextWriterWriteAttribute(writer, (xmlChar *) argname, (xmlChar *) str); } foreach(arg, arg_strings) { char *str = (char *) lfirst(arg); xmlTextWriterWriteRaw(writer, (xmlChar *) str); } xmlTextWriterEndElement(writer); /* we MUST do this now to flush data out to the buffer ... */ xmlFreeTextWriter(writer); writer = NULL; result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { if (writer) xmlFreeTextWriter(writer); if (buf) xmlBufferFree(buf); pg_xml_done(xmlerrcxt, true); PG_RE_THROW(); } PG_END_TRY(); xmlBufferFree(buf); pg_xml_done(xmlerrcxt, false); return result; #else NO_XML_SUPPORT(); return NULL; #endif }
Datum xmlexists | ( | PG_FUNCTION_ARGS | ) |
Definition at line 3963 of file xml.c.
References NO_XML_SUPPORT, NULL, PG_GETARG_TEXT_P, PG_GETARG_XML_P, and PG_RETURN_BOOL.
{ #ifdef USE_LIBXML text *xpath_expr_text = PG_GETARG_TEXT_P(0); xmltype *data = PG_GETARG_XML_P(1); int res_nitems; xpath_internal(xpath_expr_text, data, NULL, &res_nitems, NULL); PG_RETURN_BOOL(res_nitems > 0); #else NO_XML_SUPPORT(); return 0; #endif }
xmltype* xmlparse | ( | text * | data, | |
XmlOptionType | xmloption_arg, | |||
bool | preserve_whitespace | |||
) |
Definition at line 703 of file xml.c.
References GetDatabaseEncoding(), and NO_XML_SUPPORT.
Referenced by ExecEvalXml(), and texttoxml().
{ #ifdef USE_LIBXML xmlDocPtr doc; doc = xml_parse(data, xmloption_arg, preserve_whitespace, GetDatabaseEncoding()); xmlFreeDoc(doc); return (xmltype *) data; #else NO_XML_SUPPORT(); return NULL; #endif }
Definition at line 721 of file xml.c.
References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, ereport, errcode(), errdetail(), errmsg(), ERROR, initStringInfo(), NO_XML_SUPPORT, NULL, pfree(), pg_strcasecmp(), stringinfo_to_xmltype(), and text_to_cstring().
Referenced by ExecEvalXml().
{ #ifdef USE_LIBXML xmltype *result; StringInfoData buf; if (pg_strcasecmp(target, "xml") == 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), /* really */ errmsg("invalid XML processing instruction"), errdetail("XML processing instruction target name cannot be \"%s\".", target))); /* * Following the SQL standard, the null check comes after the syntax check * above. */ *result_is_null = arg_is_null; if (*result_is_null) return NULL; initStringInfo(&buf); appendStringInfo(&buf, "<?%s", target); if (arg != NULL) { char *string; string = text_to_cstring(arg); if (strstr(string, "?>") != NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION), errmsg("invalid XML processing instruction"), errdetail("XML processing instruction cannot contain \"?>\"."))); appendStringInfoChar(&buf, ' '); appendStringInfoString(&buf, string + strspn(string, " ")); pfree(string); } appendStringInfoString(&buf, "?>"); result = stringinfo_to_xmltype(&buf); pfree(buf.data); return result; #else NO_XML_SUPPORT(); return NULL; #endif }
Definition at line 773 of file xml.c.
References appendStringInfoString(), initStringInfo(), NO_XML_SUPPORT, NULL, stringinfo_to_xmltype(), text_to_cstring(), VARSIZE, XML_STANDALONE_NO, XML_STANDALONE_NO_VALUE, XML_STANDALONE_OMITTED, and XML_STANDALONE_YES.
Referenced by ExecEvalXml().
{ #ifdef USE_LIBXML char *str; size_t len; xmlChar *orig_version; int orig_standalone; StringInfoData buf; len = VARSIZE(data) - VARHDRSZ; str = text_to_cstring((text *) data); parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone); if (version) orig_version = xml_text2xmlChar(version); else orig_version = NULL; switch (standalone) { case XML_STANDALONE_YES: orig_standalone = 1; break; case XML_STANDALONE_NO: orig_standalone = 0; break; case XML_STANDALONE_NO_VALUE: orig_standalone = -1; break; case XML_STANDALONE_OMITTED: /* leave original value */ break; } initStringInfo(&buf); print_xml_decl(&buf, orig_version, 0, orig_standalone); appendStringInfoString(&buf, str + len); return stringinfo_to_xmltype(&buf); #else NO_XML_SUPPORT(); return NULL; #endif }
Datum xmltotext | ( | PG_FUNCTION_ARGS | ) |
Definition at line 556 of file xml.c.
References PG_GETARG_XML_P, and PG_RETURN_TEXT_P.
{ xmltype *data = PG_GETARG_XML_P(0); /* It's actually binary compatible. */ PG_RETURN_TEXT_P((text *) data); }
text* xmltotext_with_xmloption | ( | xmltype * | data, | |
XmlOptionType | xmloption_arg | |||
) |
Definition at line 566 of file xml.c.
References ereport, errcode(), errmsg(), ERROR, xml_is_document(), and XMLOPTION_DOCUMENT.
Referenced by ExecEvalXml().
{ if (xmloption_arg == XMLOPTION_DOCUMENT && !xml_is_document(data)) ereport(ERROR, (errcode(ERRCODE_NOT_AN_XML_DOCUMENT), errmsg("not an XML document"))); /* It's actually binary compatible, save for the above check. */ return (text *) data; }
Datum xmlvalidate | ( | PG_FUNCTION_ARGS | ) |
Datum xpath | ( | PG_FUNCTION_ARGS | ) |
Definition at line 3936 of file xml.c.
References construct_empty_array(), CurrentMemoryContext, makeArrayResult(), NO_XML_SUPPORT, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_P, PG_GETARG_XML_P, PG_RETURN_ARRAYTYPE_P, and XMLOID.
{ #ifdef USE_LIBXML text *xpath_expr_text = PG_GETARG_TEXT_P(0); xmltype *data = PG_GETARG_XML_P(1); ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2); int res_nitems; ArrayBuildState *astate; xpath_internal(xpath_expr_text, data, namespaces, &res_nitems, &astate); if (res_nitems == 0) PG_RETURN_ARRAYTYPE_P(construct_empty_array(XMLOID)); else PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext)); #else NO_XML_SUPPORT(); return 0; #endif }
Datum xpath_exists | ( | PG_FUNCTION_ARGS | ) |
Definition at line 3986 of file xml.c.
References NO_XML_SUPPORT, NULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_P, PG_GETARG_XML_P, and PG_RETURN_BOOL.
{ #ifdef USE_LIBXML text *xpath_expr_text = PG_GETARG_TEXT_P(0); xmltype *data = PG_GETARG_XML_P(1); ArrayType *namespaces = PG_GETARG_ARRAYTYPE_P(2); int res_nitems; xpath_internal(xpath_expr_text, data, namespaces, &res_nitems, NULL); PG_RETURN_BOOL(res_nitems > 0); #else NO_XML_SUPPORT(); return 0; #endif }
static void xsd_schema_element_end | ( | StringInfo | result | ) | [static] |
Definition at line 2715 of file xml.c.
References appendStringInfoString().
Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().
{ appendStringInfoString(result, "</xsd:schema>"); }
static void xsd_schema_element_start | ( | StringInfo | result, | |
const char * | targetns | |||
) | [static] |
Definition at line 2698 of file xml.c.
References appendStringInfo(), appendStringInfoString(), and NAMESPACE_XSD.
Referenced by database_to_xmlschema_internal(), map_sql_table_to_xmlschema(), and schema_to_xmlschema_internal().
{ appendStringInfoString(result, "<xsd:schema\n" " xmlns:xsd=\"" NAMESPACE_XSD "\""); if (strlen(targetns) > 0) appendStringInfo(result, "\n" " targetNamespace=\"%s\"\n" " elementFormDefault=\"qualified\"", targetns); appendStringInfoString(result, ">\n\n"); }
int xmlbinary |
Definition at line 95 of file xml.c.
Referenced by map_sql_type_to_xmlschema_type(), and map_sql_value_to_xml_value().
int xmloption |
Definition at line 96 of file xml.c.
Referenced by _copyXmlExpr(), _copyXmlSerialize(), _equalXmlExpr(), _equalXmlSerialize(), _outXmlExpr(), _outXmlSerialize(), _readXmlExpr(), texttoxml(), xml_in(), xml_is_well_formed(), and xml_recv().