![]() |
ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
Background worker registration and IPC primitives for mmap-backed storage. More...
#include "provsql_mmap.h"#include "provsql_rmgr.h"#include "provsql_shmem.h"#include "provsql_utils.h"#include <errno.h>#include <unistd.h>#include <poll.h>#include <math.h>#include <assert.h>#include "postgres.h"#include "access/xact.h"#include "postmaster/bgworker.h"#include "fmgr.h"#include "funcapi.h"#include "utils/array.h"#include "access/htup_details.h"#include "utils/builtins.h"#include "circuit_cache.h"
Go to the source code of this file.
Macros | |
| #define | WORKER_READ_BUFFER (64 * 1024) |
Functions | |
| bool | provsql_worker_buffered (void) |
Whether the worker's read buffer holds unread bytes, which poll() cannot see. | |
| bool | provsql_worker_read (void *dst, size_t n) |
| The worker's buffered read of the request pipe: what the pipe holds is read in one call, and the messages are parsed from the buffer. | |
| bool | provsql_read_all (int fd, void *dst, size_t n) |
Read exactly n bytes from fd into dst; false on EOF/error. | |
| void | provsql_mmap_worker (Datum ignored) |
| Entry point for the ProvSQL mmap background worker. | |
| void | RegisterProvSQLMMapWorker (void) |
| Register the ProvSQL mmap background worker with PostgreSQL. | |
| static void | provsql_store_sync_barrier (void) |
| Send the sync barrier and wait for the worker's acknowledgement. | |
| static void | provsql_store_xact_callback (XactEvent event, void *arg) |
| static void | provsql_log_store_write (const char *data, size_t len) |
| What every store mutation does before it reaches the pipe: refuse it on a standby, and write it to the WAL. | |
| static void | provsql_before_store_write (const char *data, size_t len) |
| The same, for a mutation made by a live transaction: it also arms the at-commit sync barrier. | |
| void | provsql_store_note_write (void) |
| Note that this transaction has written to the circuit store. | |
| bool | provsql_store_written (void) |
| Whether this transaction has written to the circuit store. | |
| void | provsql_circuit_cleanup_request (bool dry_run, const pg_uuid_t *roots, int64 nb_roots, provsql_cleanup_result *out) |
Ask the worker to rebuild this database's store, keeping only what roots reach. | |
| void | provsql_replay_store_message (const char *data, size_t len) |
| Feed a logged store message back to the worker. | |
| Datum | check_store (PG_FUNCTION_ARGS) |
| Report what does not add up in this database's circuit store. | |
| gate_type | provsql_fetch_gate (const pg_uuid_t *token, unsigned *nb_children_out, pg_uuid_t **children_out) |
| PostgreSQL-callable wrapper for get_gate_type(). | |
| Datum | get_gate_type (PG_FUNCTION_ARGS) |
| void | provsql_internal_create_gate (const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children_data) |
| Internal entry point behind create_gate(): cache + worker IPC. | |
| static provsql_set_prob_result | provsql_send_set_prob (const pg_uuid_t *token, double prob, double *existing, bool tracked) |
| Send a probability write and read back what the store made of it. | |
| provsql_set_prob_result | provsql_internal_set_prob (const pg_uuid_t *token, double prob, double *existing) |
| Write a gate's probability from in-extension C/C++ code. | |
| void | provsql_internal_clear_prob (const pg_uuid_t *token) |
| Drop a gate's probability, leaving it as it was before anyone wrote one. | |
| bool | provsql_internal_get_prob_written (const pg_uuid_t *token, double *prob) |
| Report whether a probability has been written on a gate. | |
| void | provsql_internal_create_gate_with (const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children, bool has_infos, unsigned info1, unsigned info2, const char *extra) |
| Create a gate together with its infos and its text, in one message that is not answered. | |
| Datum | create_gate (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for create_gate(). | |
| static void | send_unanswered (const char *msg, size_t len) |
| Datum | set_infos (PG_FUNCTION_ARGS) |
Entry point of the set_infos of earlier versions' scripts. | |
| Datum | set_extra (PG_FUNCTION_ARGS) |
Entry point of the set_extra of earlier versions' scripts. | |
| Datum | get_extra (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for get_extra(). | |
| Datum | get_nb_gates (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for get_nb_gates(). | |
| Datum | get_children (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for get_children(). | |
| Datum | get_prob (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for get_prob(). | |
| Datum | get_infos (PG_FUNCTION_ARGS) |
| PostgreSQL-callable wrapper for get_infos(). | |
Variables | |
| char | buffer [PIPE_BUF] ={} |
Shared write buffer used with STARTWRITEM / ADDWRITEM / SENDWRITEM. | |
| unsigned | bufferpos =0 |
Current write position within buffer. | |
| static char | worker_buffer [WORKER_READ_BUFFER] |
| static size_t | worker_buffer_pos = 0 |
| static size_t | worker_buffer_len = 0 |
| bool | provsql_synchronous_commit = false |
| Global variable set by the provsql.synchronous_commit run-time configuration parameter: when true, a transaction that has written to the circuit store forces the store to stable storage before it commits. | |
| static bool | store_written = false |
| Whether the current transaction has written anything to the store. | |
| static bool | store_callbacks_registered = false |
Background worker registration and IPC primitives for mmap-backed storage.
Implements the PostgreSQL background worker lifecycle functions declared in provsql_mmap.h:
RegisterProvSQLMMapWorker(): registers the worker with the postmaster during _PG_init().provsql_mmap_worker(): worker entry point; sets up signal handlers and enters provsql_mmap_main_loop().The IPC between normal backends and the background worker is handled in MMappedCircuit.cpp. This file provides the PostgreSQL-specific glue (background worker API, signal handling).
Also declares the shared write buffer buffer[] and position counter bufferpos used by the STARTWRITEM / ADDWRITEM / SENDWRITEM macros in provsql_mmap.h.
The gate-creation SQL functions (e.g. create_gate()) that backends call are also implemented here; they acquire the IPC lock, write a message to the background worker, and wait for an acknowledgment.
Definition in file provsql_mmap.c.
| #define WORKER_READ_BUFFER (64 * 1024) |
Definition at line 76 of file provsql_mmap.c.
| Datum check_store | ( | PG_FUNCTION_ARGS | ) |
Report what does not add up in this database's circuit store.
A store nothing has damaged answers zero to every count. A non-zero one means a write was interrupted at a point the ordering rules do not cover, or that a set of files was copied at different instants – a file-level backup of a running server, or a base backup. provsql.circuit_cleanup() rebuilds the store from what is still reachable.
Definition at line 394 of file provsql_mmap.c.

| Datum create_gate | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for create_gate().
Definition at line 783 of file provsql_mmap.c.

| Datum get_children | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for get_children().
Definition at line 969 of file provsql_mmap.c.

| Datum get_extra | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for get_extra().
Definition at line 911 of file provsql_mmap.c.

| Datum get_gate_type | ( | PG_FUNCTION_ARGS | ) |
| Datum get_infos | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for get_infos().
Definition at line 1067 of file provsql_mmap.c.

| Datum get_nb_gates | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for get_nb_gates().
Definition at line 947 of file provsql_mmap.c.

| Datum get_prob | ( | PG_FUNCTION_ARGS | ) |
PostgreSQL-callable wrapper for get_prob().
Definition at line 1037 of file provsql_mmap.c.

|
static |
The same, for a mutation made by a live transaction: it also arms the at-commit sync barrier.
Definition at line 267 of file provsql_mmap.c.


| void provsql_circuit_cleanup_request | ( | bool | dry_run, |
| const pg_uuid_t * | roots, | ||
| int64 | nb_roots, | ||
| provsql_cleanup_result * | out ) |
Ask the worker to rebuild this database's store, keeping only what roots reach.
The caller must hold the database exclusively; see provsql.circuit_cleanup in circuit_cleanup.c.
Definition at line 287 of file provsql_mmap.c.


| gate_type provsql_fetch_gate | ( | const pg_uuid_t * | token, |
| unsigned * | nb_children_out, | ||
| pg_uuid_t ** | children_out ) |
PostgreSQL-callable wrapper for get_gate_type().
Fetch a gate's type and children, cache-first with a worker round-trip (and cache fill) on a miss.
On cache miss this fetches BOTH the gate type and its children from the worker, in one critical section, then caches them together. If we cached only the type (with an empty children list), a subsequent get_children() call for the same token would consult the cache, find the entry, and return 0 children : never querying the worker for the real children. provsql.provenance_evaluate hits exactly that pattern (it calls get_gate_type first, then unnest(get_children(...))) and silently folds plus/times gates over an empty set.
Fetch a gate's type and children, cache-first with a worker round-trip (and cache fill) on a miss. Factored out of the get_gate_type() wrapper for in-extension callers that walk the circuit from C (e.g. the annotation-transparent set_prob()). On return *children_out is a calloc'd array to be freed by the caller, or NULL when the gate has no children.
Definition at line 456 of file provsql_mmap.c.


| void provsql_internal_clear_prob | ( | const pg_uuid_t * | token | ) |
Drop a gate's probability, leaving it as it was before anyone wrote one.
The rollback path of probability_store.c, and the only way to unset a probability: there is none from SQL. Unlike a write it does not arm the at-commit sync barrier – it runs when the transaction that would have committed is already gone.
Definition at line 679 of file provsql_mmap.c.


| void provsql_internal_create_gate | ( | const pg_uuid_t * | token, |
| gate_type | type, | ||
| unsigned | nb_children, | ||
| const pg_uuid_t * | children_data ) |
Internal entry point behind create_gate(): cache + worker IPC.
Create a gate from in-extension C/C++ code (cache + worker IPC).
Factored out of the SQL-callable wrapper so in-extension C/C++ code (e.g. the decomposition-aligned reachability materialiser) can create gates without Datum marshalling or gate-type-OID lookups. Same semantics: write-through to the per-session cache, then the C message to the background worker; MMappedCircuit::createGate is idempotent on already-mapped tokens.
Definition at line 545 of file provsql_mmap.c.


| void provsql_internal_create_gate_with | ( | const pg_uuid_t * | token, |
| gate_type | type, | ||
| unsigned | nb_children, | ||
| const pg_uuid_t * | children, | ||
| bool | has_infos, | ||
| unsigned | info1, | ||
| unsigned | info2, | ||
| const char * | extra ) |
Create a gate together with its infos and its text, in one message that is not answered.
For the gates whose address determines what they record (a value gate and its text, an annotation, a comparison and its operator, an aggregate), so that the write-once rule has nothing to refuse and nobody needs to wait for its answer. extra NULL records no text; has_infos false records no infos.
Definition at line 706 of file provsql_mmap.c.


| bool provsql_internal_get_prob_written | ( | const pg_uuid_t * | token, |
| double * | prob ) |
Report whether a probability has been written on a gate.
Distinct from get_prob(), which reports the value an evaluation would use and so answers 1 for a gate nobody gave a probability.
| token | UUID of the gate. |
| prob | On true return, the written probability. |
Definition at line 684 of file provsql_mmap.c.


| provsql_set_prob_result provsql_internal_set_prob | ( | const pg_uuid_t * | token, |
| double | prob, | ||
| double * | existing ) |
Write a gate's probability from in-extension C/C++ code.
Probabilities are written once (see MMappedCircuit::setProb), so this reports which of the four cases applied rather than a bare success flag. Callers that write a probability on a gate they have just created can treat anything but PROVSQL_SET_PROB_NOT_PROB_GATE as success; set_prob() itself raises on PROVSQL_SET_PROB_ALREADY_SET.
Note that this is the raw store operation: it does not record the write in the transaction's undo list. SQL-level writers go through provsql_set_prob_tracked() in probability_store.c so a rollback drops what they wrote.
| token | UUID of the gate. |
| prob | Probability value in [0,1], or NaN to clear. |
| existing | On PROVSQL_SET_PROB_ALREADY_SET, the stored value. |
Definition at line 672 of file provsql_mmap.c.


|
static |
What every store mutation does before it reaches the pipe: refuse it on a standby, and write it to the WAL.
data is the complete message, opcode first.
Definition at line 251 of file provsql_mmap.c.


| void provsql_mmap_worker | ( | Datum | ignored | ) |
Entry point for the ProvSQL mmap background worker.
Called by the postmaster when it launches the background worker. Enters the main loop (provsql_mmap_main_loop()) and never returns normally. The single Datum argument is required by the background-worker API but is not used.
Definition at line 146 of file provsql_mmap.c.

| bool provsql_read_all | ( | int | fd, |
| void * | dst, | ||
| size_t | n ) |
Read exactly n bytes from fd into dst; false on EOF/error.
Definition at line 111 of file provsql_mmap.c.
| void provsql_replay_store_message | ( | const char * | data, |
| size_t | len ) |
Feed a logged store message back to the worker.
Implemented in provsql_mmap.c, where the IPC primitives live.
Definition at line 341 of file provsql_mmap.c.

|
static |
Send a probability write and read back what the store made of it.
tracked arms the at-commit sync barrier; the one caller that passes false is the rollback path, which runs when the transaction that would have committed is already gone.
Definition at line 642 of file provsql_mmap.c.


| void provsql_store_note_write | ( | void | ) |
Note that this transaction has written to the circuit store.
Arms the at-commit sync barrier (provsql.synchronous_commit) and the PREPARE TRANSACTION refusal.
Definition at line 273 of file provsql_mmap.c.


|
static |
Send the sync barrier and wait for the worker's acknowledgement.
Definition at line 209 of file provsql_mmap.c.


| bool provsql_store_written | ( | void | ) |
Whether this transaction has written to the circuit store.
Definition at line 282 of file provsql_mmap.c.

|
static |
Definition at line 225 of file provsql_mmap.c.


| bool provsql_worker_buffered | ( | void | ) |
Whether the worker's read buffer holds unread bytes, which poll() cannot see.
Definition at line 80 of file provsql_mmap.c.

| bool provsql_worker_read | ( | void * | dst, |
| size_t | n ) |
The worker's buffered read of the request pipe: what the pipe holds is read in one call, and the messages are parsed from the buffer.
false on EOF or error.
Definition at line 85 of file provsql_mmap.c.
| void RegisterProvSQLMMapWorker | ( | void | ) |
Register the ProvSQL mmap background worker with PostgreSQL.
Must be called from the extension's _PG_init() function so that the postmaster starts the worker on the next connection.
Definition at line 162 of file provsql_mmap.c.

|
static |
Definition at line 845 of file provsql_mmap.c.


| Datum set_extra | ( | PG_FUNCTION_ARGS | ) |
Entry point of the set_extra of earlier versions' scripts.
Definition at line 887 of file provsql_mmap.c.

| Datum set_infos | ( | PG_FUNCTION_ARGS | ) |
Entry point of the set_infos of earlier versions' scripts.
Definition at line 864 of file provsql_mmap.c.

| char buffer[PIPE_BUF] ={} |
Shared write buffer used with STARTWRITEM / ADDWRITEM / SENDWRITEM.
Definition at line 69 of file provsql_mmap.c.
| unsigned bufferpos =0 |
Current write position within buffer.
Definition at line 70 of file provsql_mmap.c.
| bool provsql_synchronous_commit = false |
Global variable set by the provsql.synchronous_commit run-time configuration parameter: when true, a transaction that has written to the circuit store forces the store to stable storage before it commits.
Definition at line 202 of file provsql_mmap.c.
|
static |
Definition at line 206 of file provsql_mmap.c.
|
static |
Whether the current transaction has written anything to the store.
Definition at line 205 of file provsql_mmap.c.
|
static |
Definition at line 77 of file provsql_mmap.c.
|
static |
Definition at line 78 of file provsql_mmap.c.
|
static |
Definition at line 78 of file provsql_mmap.c.