![]() |
ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
OID lookup, constants cache, and utility functions for ProvSQL. More...
#include "postgres.h"#include "access/htup_details.h"#include "access/heapam.h"#include "access/genam.h"#include "miscadmin.h"#include "catalog/indexing.h"#include "catalog/namespace.h"#include "catalog/pg_attribute.h"#include "catalog/pg_constraint.h"#include "catalog/pg_index.h"#include "catalog/pg_type.h"#include "catalog/pg_enum.h"#include "catalog/pg_namespace.h"#include "catalog/pg_operator.h"#include "fmgr.h"#include "nodes/value.h"#include "parser/parse_func.h"#include "utils/fmgroids.h"#include "utils/syscache.h"#include "utils/lsyscache.h"#include "utils/inval.h"#include <string.h>#include "provsql_utils.h"
Go to the source code of this file.
Classes | |
| struct | table_info_cache_entry |
| struct | ancestry_cache_entry |
| struct | key_cache_entry |
Macros | |
| #define | table_open(r, l) |
| #define | table_close(r, l) |
| #define | CheckOid(o) |
| #define | GET_GATE_TYPE_OID(x) |
| #define | GET_GATE_TYPE_OID_OPTIONAL(x) |
Functions | |
| static Oid | binary_oper_exact (List *opname, Oid arg1, Oid arg2) |
| Look up an exactly matching binary operator OID. | |
| Oid | find_equality_operator (Oid ltypeId, Oid rtypeId) |
| Find the equality operator OID for two given types. | |
| static Oid | get_func_oid (char *s) |
Return the OID of a globally qualified function named s. | |
| static Oid | get_provsql_func_oid (char *s) |
Return the OID of a provsql-schema function named s. | |
| static void | OperatorGet (const char *operatorName, Oid operatorNamespace, Oid leftObjectId, Oid rightObjectId, Oid *operatorObjectId, Oid *functionObjectId) |
| Retrieve operator and function OIDs for a named operator. | |
| static Oid | get_enum_oid (Oid enumtypoid, const char *label) |
| Return the OID of a specific enum label within an enum type. | |
| static constants_t | initialize_constants (bool failure_if_not_possible) |
Query the system catalogs to populate a fresh constants_t. | |
| constants_t | get_constants (bool failure_if_not_possible) |
| Retrieve the cached OID constants for the current database. | |
| static int | table_info_cache_find (Oid relid, int *insert_at) |
Find relid in the cache. | |
| static void | table_info_cache_insert (int pos, Oid relid, bool present, const ProvenanceTableInfo *info) |
Insert a fresh entry at pos (which must be the value returned by the most recent table_info_cache_find that reported a miss). | |
| static void | invalidate_table_info_cache_callback (Datum arg, Oid relid) |
| Relcache callback: PostgreSQL fires this whenever a relation's relcache entry is invalidated (locally or via shared invalidation from another backend). | |
| bool | provsql_lookup_table_info (Oid relid, ProvenanceTableInfo *out) |
| Look up per-table provenance metadata with a backend-local cache. | |
| static int | ancestry_cache_find (Oid relid, int *insert_at) |
| static void | ancestry_cache_insert (int pos, Oid relid, bool present, uint16 ancestor_n, const Oid *ancestors) |
| static void | invalidate_ancestry_cache_callback (Datum arg, Oid relid) |
| bool | provsql_lookup_ancestry (Oid relid, uint16 *ancestor_n_out, Oid *ancestors_out) |
| Look up the base-ancestor set of a tracked relation. | |
| static int | key_cache_find (Oid relid, int *insert_at) |
| static void | key_cache_insert (int pos, Oid relid, const ProvenanceRelationKeys *keys) |
| static void | invalidate_key_cache_callback (Datum arg, Oid relid) |
| static bool | fetch_relation_keys (Oid relid, ProvenanceRelationKeys *out) |
Read the PRIMARY-KEY and NOT-NULL-UNIQUE keys of relid from the system catalogs. | |
| bool | provsql_lookup_relation_keys (Oid relid, ProvenanceRelationKeys *out) |
| Look up the PRIMARY-KEY and NOT-NULL-UNIQUE keys of a relation with a backend-local cache. | |
| Datum | reset_constants_cache (PG_FUNCTION_ARGS) |
| SQL function to invalidate the OID constants cache. | |
Variables | |
| const char * | gate_type_name [] |
| Names of gate types. | |
| static database_constants_t * | constants_cache |
| Per-database OID constants cache (sorted by database OID). | |
| static unsigned | constants_cache_len =0 |
Number of valid entries in constants_cache. | |
| static table_info_cache_entry * | table_info_cache = NULL |
Sorted by relid. | |
| static unsigned | table_info_cache_len = 0 |
| static bool | table_info_callback_registered = false |
| static ancestry_cache_entry * | ancestry_cache = NULL |
| static unsigned | ancestry_cache_len = 0 |
| static bool | ancestry_callback_registered = false |
| static key_cache_entry * | key_cache = NULL |
| static unsigned | key_cache_len = 0 |
| static bool | key_cache_callback_registered = false |
OID lookup, constants cache, and utility functions for ProvSQL.
Implements the functions declared in provsql_utils.h:
get_constants(): retrieves and caches per-database OIDs for all ProvSQL types, functions, and operators.find_equality_operator(): looks up the = operator OID for a given pair of types.The constants cache is a sorted, dynamically-grown array of database_constants_t records (one per PostgreSQL database OID) stored in process-local memory and searched with binary search. The reset_constants_cache() SQL function forces a cache invalidation for the current database, which is needed after ALTER EXTENSION.
Several helper functions (get_func_oid, get_provsql_func_oid, OperatorGet, get_enum_oid, binary_oper_exact) are adapted from PostgreSQL source code that is not exported as a public API.
Definition in file provsql_utils.c.
| #define CheckOid | ( | o | ) |
| #define GET_GATE_TYPE_OID | ( | x | ) |
| #define GET_GATE_TYPE_OID_OPTIONAL | ( | x | ) |
| #define table_close | ( | r, | |
| l ) |
Definition at line 28 of file provsql_utils.c.
| #define table_open | ( | r, | |
| l ) |
Definition at line 27 of file provsql_utils.c.
|
static |
|
static |
|
static |
Look up an exactly matching binary operator OID.
Copied and adapted from parse_oper.c (PostgreSQL internals, not exported). Returns InvalidOid if no exact match exists.
| opname | Qualified operator name (a List of String nodes). |
| arg1 | OID of the left operand type. |
| arg2 | OID of the right operand type. |
InvalidOid. Definition at line 89 of file provsql_utils.c.

|
static |
Read the PRIMARY-KEY and NOT-NULL-UNIQUE keys of relid from the system catalogs.
Scans pg_constraint for entries with conrelid = relid and contype IN ('p','u'), then resolves each constraint's column list via pg_index.indkey (the constraint's index is recorded in pg_constraint.conindid). For UNIQUE constraints, verifies every constituent column has pg_attribute.attnotnull = true; UNIQUE-with-NULLABLE constraints are rejected (UNIQUE allows multiple rows with NULL in PostgreSQL, so the ∅ → attr FD does not hold without NOT NULL).
Stores up to PROVSQL_KEY_CACHE_MAX_KEYS keys; subsequent keys are silently dropped. Skips constraints whose column count exceeds PROVSQL_KEY_CACHE_MAX_KEY_COLS. Both elisions are conservatively safe (the §2 detector simply does not see the dropped FDs).
Definition at line 926 of file provsql_utils.c.

| Oid find_equality_operator | ( | Oid | ltypeId, |
| Oid | rtypeId ) |
Find the equality operator OID for two given types.
Searches pg_operator for the = operator that accepts ltypeId on the left and rtypeId on the right.
| ltypeId | OID of the left operand type. |
| rtypeId | OID of the right operand type. |
InvalidOid if none is found. Definition at line 129 of file provsql_utils.c.


| constants_t get_constants | ( | bool | failure_if_not_possible | ) |
Retrieve the cached OID constants for the current database.
On first call (or after a cache miss) this function looks up the OIDs of all ProvSQL-specific types, functions, and operators in the system catalogs and stores them in a per-database cache. Subsequent calls return the cached values without touching the catalogs.
| failure_if_not_possible | If true, call provsql_error when the ProvSQL schema cannot be found (e.g. the extension is not installed in the current database). If false, return a constants_t with ok==false instead of aborting. |
constants_t whose ok field is true on success. Definition at line 530 of file provsql_utils.c.


|
static |
Return the OID of a specific enum label within an enum type.
| enumtypoid | OID of the enum type (e.g. provenance_gate). |
| label | C-string label of the enum value to look up. |
pg_enum row, or InvalidOid if the label is not present. Definition at line 274 of file provsql_utils.c.
|
static |
Return the OID of a globally qualified function named s.
Looks up the function in the default search path. Returns 0 if no matching function is found.
| s | Function name (unqualified). |
Definition at line 169 of file provsql_utils.c.

|
static |
Return the OID of a provsql-schema function named s.
Looks up the function in the provsql schema. Returns 0 if not found.
| s | Function name (without schema prefix). |
Definition at line 195 of file provsql_utils.c.

|
static |
Query the system catalogs to populate a fresh constants_t.
Performs all OID lookups required by ProvSQL in a single pass through the system caches. The CheckOid() macro aborts (or returns early, depending on failure_if_not_possible) if any OID resolves to InvalidOid.
| failure_if_not_possible | If true, raise a provsql_error when any OID cannot be resolved. If false, return a constants_t with ok==false instead. |
constants_t on success, or ok==false on failure when failure_if_not_possible is false. Abort or return early if OID field o of constants is invalid.
Look up the OID of provenance_gate enum value x and store it in constants.
Like GET_GATE_TYPE_OID but tolerates a missing enum value.
Used for gate types added in releases newer than the oldest schema the extension_upgrade test exercises (currently 1.0.0). An intermediate state where a 1.0.0 database has been bound to a newer shared library is possible (e.g. between CREATE EXTENSION VERSION and ALTER EXTENSION UPDATE) and must not abort get_constants – the missing OID stays InvalidOid and any attempt to actually create such a gate fails later in create_gate's "Invalid gate type" branch. When the upgrade scripts catch up, the lookup succeeds and the gate becomes usable normally. No state for InvalidOid is stored, so the field keeps its zero-init value (which is InvalidOid).
Definition at line 310 of file provsql_utils.c.


|
static |
Definition at line 763 of file provsql_utils.c.


|
static |
Definition at line 893 of file provsql_utils.c.


|
static |
Relcache callback: PostgreSQL fires this whenever a relation's relcache entry is invalidated (locally or via shared invalidation from another backend).
relid == InvalidOid means "invalidate everything."
Definition at line 635 of file provsql_utils.c.


|
static |
|
static |
|
static |
Retrieve operator and function OIDs for a named operator.
Copied and adapted from pg_operator.c (PostgreSQL internals, not exported). Looks up the operator by name, namespace, and operand types in the system cache.
| operatorName | Operator symbol string (e.g. "<>"). |
| operatorNamespace | OID of the schema containing the operator. |
| leftObjectId | OID of the left operand type. |
| rightObjectId | OID of the right operand type. |
| operatorObjectId | Output: OID of the operator, or 0 if not found. |
| functionObjectId | Output: OID of the underlying function, or 0. |
Definition at line 227 of file provsql_utils.c.

| bool provsql_lookup_ancestry | ( | Oid | relid, |
| uint16 * | ancestor_n_out, | ||
| Oid * | ancestors_out ) |
Look up the base-ancestor set of a tracked relation.
Per-backend cached over IPC. Returns the ancestor set when relid is tracked and the registry has a non-empty entry for it. false either when relid has no metadata record at all (the relation was never run through add_provenance / repair_key) or when the record exists but ancestor_n == 0 (the CTAS hook hasn't populated the lineage yet, or the registry was explicitly cleared). The two failure modes share the false return because both make the safe-query rewriter take the conservative refuse path – there is no use case for treating them differently.
Backed by the same per-backend cache as provsql_lookup_table_info and invalidated through the same relcache-invalidation callback, so concurrent set_ancestors / add_provenance / repair_key calls in other backends are reflected here without polling.
| relid | pg_class OID of the relation to look up. |
| ancestor_n_out | On true return, count of valid entries in ancestors_out. |
| ancestors_out | On true return, the sorted-deduplicated ancestor OIDs (caller-allocated buffer of PROVSQL_TABLE_INFO_MAX_ANCESTORS Oid). |
true on a non-empty ancestor set; false otherwise. Definition at line 777 of file provsql_utils.c.


| bool provsql_lookup_relation_keys | ( | Oid | relid, |
| ProvenanceRelationKeys * | out ) |
Look up the PRIMARY-KEY and NOT-NULL-UNIQUE keys of a relation with a backend-local cache.
Companion to provsql_lookup_table_info. The cache lives in a separate backing array with its own relcache-invalidation callback so that a future ALTER TABLE that adds / drops a constraint refreshes the next lookup without polling. Returns true when the relation has at least one PRIMARY KEY or NOT-NULL UNIQUE constraint; false otherwise (in which case *out is filled with key_n = 0). Safe to call from the planner hot path.
| relid | pg_class OID of the relation to inspect. |
| out | Filled on return. out->relid is set to relid regardless of return value; out->keys holds up to PROVSQL_KEY_CACHE_MAX_KEYS keys. |
Definition at line 1014 of file provsql_utils.c.


| bool provsql_lookup_table_info | ( | Oid | relid, |
| ProvenanceTableInfo * | out ) |
Look up per-table provenance metadata with a backend-local cache.
Resolves to a cached value when the relation's relcache entry has not been invalidated since the last fetch; otherwise issues one 's' IPC to the background worker. The cache is invalidated via CacheRegisterRelcacheCallback, so concurrent add_provenance / repair_key / remove_provenance in other backends are reflected here without polling.
Safe to call from the planner hot path.
| relid | pg_class OID of the relation to look up. |
| out | On true return, filled with the stored record. |
true if a record exists for relid, false otherwise. Definition at line 649 of file provsql_utils.c.


| Datum reset_constants_cache | ( | PG_FUNCTION_ARGS | ) |
SQL function to invalidate the OID constants cache.
Forces a fresh OID lookup for the current database on the next call to get_constants(). Must be called after ALTER EXTENSION provsql UPDATE to ensure cached OIDs are refreshed.
Definition at line 1062 of file provsql_utils.c.

|
static |
Find relid in the cache.
Returns the index on hit; otherwise -1 and writes the insertion point to *insert_at.
Definition at line 590 of file provsql_utils.c.

|
static |
Insert a fresh entry at pos (which must be the value returned by the most recent table_info_cache_find that reported a miss).
Definition at line 608 of file provsql_utils.c.

|
static |
Definition at line 721 of file provsql_utils.c.
|
static |
Definition at line 722 of file provsql_utils.c.
|
static |
Definition at line 723 of file provsql_utils.c.
|
static |
Per-database OID constants cache (sorted by database OID).
Definition at line 527 of file provsql_utils.c.
|
static |
Number of valid entries in constants_cache.
Definition at line 528 of file provsql_utils.c.
| const char* gate_type_name[] |
Names of gate types.
Definition at line 54 of file provsql_utils.c.
|
static |
Definition at line 852 of file provsql_utils.c.
|
static |
Definition at line 854 of file provsql_utils.c.
|
static |
Definition at line 853 of file provsql_utils.c.
|
static |
Sorted by relid.
Definition at line 584 of file provsql_utils.c.
|
static |
Definition at line 585 of file provsql_utils.c.
|
static |
Definition at line 586 of file provsql_utils.c.