ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
rv_families.cpp
Go to the documentation of this file.
1/**
2 * @file rv_families.cpp
3 * @brief SQL surface for the continuous-distribution family registry
4 * (@ref src/distributions/Distribution.h).
5 *
6 * Exposes @c rv_families(), the set-returning catalog of every registered
7 * @c gate_rv family: the on-disk name token, parameter count and
8 * conventional parameter symbols, and a short display label. UI clients
9 * (ProvSQL Studio's circuit inspector) read it to render families they
10 * were not hard-coded for, so a family added under
11 * @c src/distributions/ shows up without a client release.
12 */
13extern "C" {
14#include "postgres.h"
15#include "fmgr.h"
16#include "funcapi.h"
17#include "miscadmin.h"
18#include "catalog/pg_type.h"
19#include "utils/array.h"
20#include "utils/builtins.h"
21#include "utils/tuplestore.h"
22
23#include "compatibility.h" /* TYPALIGN_INT fallback for PG < 11 */
24
25PG_FUNCTION_INFO_V1(rv_families);
26}
27
29#include "provsql_error.h"
30
31#include <string>
32#include <vector>
33
34namespace {
35
36/// Build a text[] Datum from the family's parameter-name literals.
37Datum param_names_to_text_array(const provsql::DistributionFamily &fam)
38{
39 std::vector<Datum> elems;
40 for (unsigned i = 0; i < fam.nparams && i < 2; ++i) {
41 const char *name = fam.param_names[i];
42 if (!name)
43 break;
44 elems.push_back(PointerGetDatum(cstring_to_text(name)));
45 }
46 if (elems.empty())
47 return PointerGetDatum(construct_empty_array(TEXTOID));
48 ArrayType *arr = construct_array(elems.data(),
49 static_cast<int>(elems.size()),
50 TEXTOID, -1, false, TYPALIGN_INT);
51 return PointerGetDatum(arr);
52}
53
54} // namespace
55
56extern "C" Datum
57rv_families(PG_FUNCTION_ARGS)
58{
59 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
60
61 MemoryContext per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
62 MemoryContext oldcontext = MemoryContextSwitchTo(per_query_ctx);
63
64 TupleDesc tupdesc;
65 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
66 MemoryContextSwitchTo(oldcontext);
67 provsql_error("rv_families: function must return a row type");
68 }
69 tupdesc = BlessTupleDesc(tupdesc);
70
71 Tuplestorestate *tupstore = tuplestore_begin_heap(
72 rsinfo->allowedModes & SFRM_Materialize_Random, false, work_mem);
73 rsinfo->returnMode = SFRM_Materialize;
74 rsinfo->setResult = tupstore;
75 rsinfo->setDesc = tupdesc;
76
77 try {
78 for (const provsql::DistributionFamily *fam :
80 Datum values[4];
81 bool nulls[4] = {false, false, false, false};
82
83 values[0] = PointerGetDatum(cstring_to_text(fam->name));
84 values[1] = Int32GetDatum(static_cast<int32>(fam->nparams));
85 values[2] = param_names_to_text_array(*fam);
86 values[3] = PointerGetDatum(cstring_to_text(fam->label ? fam->label
87 : ""));
88
89 tuplestore_putvalues(tupstore, tupdesc, values, nulls);
90 }
91 } catch (const std::exception &e) {
92 MemoryContextSwitchTo(oldcontext);
93 provsql_error("rv_families: %s", e.what());
94 } catch (...) {
95 MemoryContextSwitchTo(oldcontext);
96 provsql_error("rv_families: unknown exception");
97 }
98
99 MemoryContextSwitchTo(oldcontext);
100 PG_RETURN_NULL();
101}
Per-family polymorphic view over a continuous gate_rv distribution (§F.1 class hierarchy).
PostgreSQL cross-version compatibility shims for ProvSQL.
#define TYPALIGN_INT
Alignment codes for the array routines (construct_array / deconstruct_array).
std::vector< const DistributionFamily * > listDistributionFamilies()
Every registered family, sorted by name token.
Uniform error-reporting macros for ProvSQL.
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
Datum rv_families(PG_FUNCTION_ARGS)
A registered family's descriptor: its complete identity.
unsigned nparams
1 or 2 (a 1-parameter family leaves p2 = 0)