18#include "catalog/pg_type.h"
19#include "utils/uuid.h"
44 output.reserve(input.size());
45 for (
char c : input) {
47 case '&': output +=
"&";
break;
48 case '<': output +=
"<";
break;
49 default: output += c;
break;
67 pg_uuid_t token = *DatumGetUUIDP(tokenDatum);
71 ss <<
"<?xml version='1.0' encoding='UTF-8'?>\n";
72 ss <<
"<prov:document xmlns:prov='http://www.w3.org/ns/prov#' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:provsql='https://provsql.org/'>\n";
77 std::unordered_map<gate_t, std::string> provenance_mapping;
80 std::vector<std::string> inputs_uuid;
81 std::transform(inputs.begin(), inputs.end(), std::back_inserter(inputs_uuid), [&c](
auto x) {
86 initialize_provenance_mapping<std::string>(constants, c, provenance_mapping, [](
const char *v) {
87 return std::string(v);
91 std::list<gate_t> to_process { root };
92 std::set<gate_t> seen;
94 while(!to_process.empty()) {
95 auto g = to_process.front();
96 to_process.pop_front();
100 ss <<
" <prov:entity prov:id='provsql:" + uuid +
"'>\n";
101 ss <<
" <prov:type xsi:type='xsd:QName'>provsql:" + std::string(
gate_type_name[type]) +
"</prov:type>\n";
102 if (type ==
gate_input && table && provenance_mapping.find(g)!=provenance_mapping.end()) {
103 ss <<
" <prov:value>" +
xmlEscape(provenance_mapping[g]) +
"</prov:value>\n";
105 ss <<
" </prov:entity>\n";
109 ss <<
" <prov:wasDerivedFrom>\n";
110 ss <<
" <prov:generatedEntity prov:ref='provsql:" + uuid +
"' />\n";
111 ss <<
" <prov:usedEntity prov:ref='provsql:" + c.
getUUID(h) +
"' />\n";
114 ss <<
" <prov:label>left</prov:label>\n";
116 ss <<
" <prov:label>right</prov:label>\n";
119 ss <<
" </prov:wasDerivedFrom>\n";
121 if(seen.find(h) == seen.end()) {
122 to_process.push_back(h);
130 ss <<
"</prov:document>\n";
140 Datum token = PG_GETARG_DATUM(0);
141 Datum table = PG_GETARG_DATUM(1);
145 text *result = (text *) palloc(VARHDRSZ + s.size() + 1);
146 SET_VARSIZE(result, VARHDRSZ + s.size());
148 memcpy((
void *) VARDATA(result),
151 PG_RETURN_TEXT_P(result);
152 }
catch(
const exception &e) {
GenericCircuit getGenericCircuit(pg_uuid_t token)
Build a GenericCircuit from the mmap store rooted at token.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
gateType getGateType(gate_t g) const
Return the type of gate g.
uuid getUUID(gate_t g) const
Return the UUID string associated with gate g.
gate_t getGate(const uuid &u)
Return (or create) the gate associated with UUID u.
In-memory provenance circuit with semiring-generic evaluation.
const std::set< gate_t > & getInputs() const
Return the set of input (leaf) gates.
Template helper for populating provenance mappings from SPI results.
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
Shared-memory segment and inter-process pipe management.
const char * gate_type_name[]
Names of gate types.
constants_t get_constants(bool failure_if_not_possible)
Retrieve the cached OID constants for the current database.
Core types, constants, and utilities shared across ProvSQL.
gate_type
Possible gate type in the provenance circuit.
@ gate_monus
M-Semiring monus.
@ gate_input
Input (variable) gate of the circuit.
string uuid2string(pg_uuid_t uuid)
Format a pg_uuid_t as a std::string.
Structure to store the value of various constants.
const char * drop_temp_table
DROP TABLE statement for the per-query temporary provenance mapping table.
bool join_with_temp_uuids(Oid table, const std::vector< std::string > &uuids)
Join a provenance mapping table with a set of UUIDs using SPI.
Datum to_provxml(PG_FUNCTION_ARGS)
PostgreSQL-callable wrapper for to_provxml().
static string to_provxml_internal(Datum tokenDatum, Datum table)
Build an XML provenance representation for a circuit token.
static string xmlEscape(const std::string &input)
Escape special XML characters in input.