ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql.c File Reference

PostgreSQL planner hook for transparent provenance tracking. More...

#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "pg_config.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_class.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "utils/jsonb.h"
#include "nodes/nodeFuncs.h"
#include "nodes/print.h"
#include "executor/executor.h"
#include "optimizer/var.h"
#include "optimizer/planner.h"
#include "parser/parse_coerce.h"
#include "parser/parse_node.h"
#include "parser/parse_oper.h"
#include "rewrite/rewriteManip.h"
#include "parser/parse_relation.h"
#include "utils/builtins.h"
#include "parser/parsetree.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/ruleutils.h"
#include "utils/syscache.h"
#include "catalog/namespace.h"
#include "catalog/pg_cast.h"
#include "commands/createas.h"
#include "executor/spi.h"
#include "tcop/utility.h"
#include "tcop/tcopprot.h"
#include <time.h>
#include "classify_query.h"
#include "joint_width_query.h"
#include "provsql_mmap.h"
#include "provsql_shmem.h"
#include "provsql_utils.h"
#include "safe_query.h"
#include "compatibility.h"
Include dependency graph for provsql.c:

Go to the source code of this file.

Classes

struct  reduce_varattno_mutator_context
 Context for the reduce_varattno_mutator tree walker. More...
struct  aggregation_type_mutator_context
 Context for the aggregation_type_mutator tree walker. More...
struct  LoweredCte
 Memo entry mapping a recursive-CTE name to its lowered scan subquery. More...
struct  contains_agg_ctx
 Context for contains_agg_walker. More...
struct  having_distinct_ctx
 Collector for AGG(DISTINCT) Aggrefs inside a HAVING clause. More...
struct  having_replace_ctx
 Context for replace_having_distinct_mutator: next outer RT index. More...
struct  aggregation_mutator_context
 Context for the aggregation_mutator tree walker. More...
struct  provenance_mutator_context
 Context for the provenance_mutator tree walker. More...
 Context for sublink_over_tracked_walker. More...
 Context for sublink_classify_walker. More...
struct  oj_cols
 Per-relation user-column descriptor for the outer-join lowering. More...
struct  oj_renum_ctx
 Var-renumber context: map varno from[i] → to[i]. More...
struct  oj_joinref_ctx
 Walker context: detect a Var referencing the join RTE index. More...
struct  oj_outer_ctx
 Outer Var remap context for the LEFT-join lowering: base-relation Vars (R_idx / S_idx) are retargeted to the new subquery (new_idx) with their attribute number mapped to the subquery column position. More...
struct  oj_decorr_ctx
 Mutator: lift a scalar subquery's body into the outer query level. More...
 Walker: count SubLink nodes (capturing the first), and capture a Var referencing varno target_varno (level 0) – used to find a Q column for the count() key. More...
struct  oj_sl_replace_ctx
 Mutator: replace the specific SubLink node target (by pointer) with replacement. More...
struct  oj_wrap_ctx
 Var-remap context for the FROM-wrapping pre-step: a Var at target_level on relation varno / attribute varattno is retargeted to newidx column pos[varno][varattno]. More...
struct  oj_param_repl_ctx
 Context for oj_param_repl_mut. More...
struct  insert_agg_token_casts_context
 Context for the insert_agg_token_casts_mutator. More...
struct  join_qual_agg_token_ctx
 Context for join_qual_has_agg_token_walker. More...
struct  retype_agg_var_ctx
 Context for retype_agg_var_walker. More...
struct  FlatAtomOrigin
 Where a flattened base atom came from, for mapping markers back. More...
struct  flatten_ctx
 Context for flatten_mut (a multi-relation conjunctive inliner). More...
struct  inert_walk_ctx
 Process the inert provenance() fetches in one query's own clauses. More...
struct  ProvSQLCtasCapture
 State captured by the pre-execution pass for the post-execution one. More...

Enumerations

enum  provsql_provenance_class_t { PROVSQL_PROVENANCE_WHERE , PROVSQL_PROVENANCE_SEMIRING , PROVSQL_PROVENANCE_ABSORPTIVE , PROVSQL_PROVENANCE_BOOLEAN }
 Values of the provsql.provenance enum GUC, from most general to most specialised. More...
enum  semiring_operation { SR_PLUS , SR_MONUS , SR_TIMES }
 Semiring operation used to combine provenance tokens. More...
enum  qual_class {
  QUAL_DETERMINISTIC , QUAL_PURE_AGG , QUAL_PURE_RV , QUAL_MIXED_AGG_DET ,
  QUAL_MIXED_RV_DET , QUAL_MIXED_AGG_RV
}
 Categorisation of a top-level WHERE conjunct. More...

Functions

static void provsql_provenance_assign_hook (int newval, void *extra)
 Assign hook of provsql.provenance: refresh the derived per-class flags.
void _PG_init (void)
 Extension initialization – called once when the shared library is loaded.
void _PG_fini (void)
 Extension teardown – restores the planner and shmem hooks.
static Query * process_query (const constants_t *constants, Query *q, bool **removed, bool wrap_root, bool top_level, bool in_boolean_rewrite, const InvFreeMarkerCtx *inv_ctx)
 Rewrite a single SELECT query to carry provenance.
static Expr * wrap_in_assume_boolean (const constants_t *constants, Expr *expr)
 Wrap expr in a provsql.assume_boolean FuncExpr.
static Expr * wrap_in_annotate (const constants_t *constants, Expr *expr, const char *cert)
 Wrap expr in a provsql.annotate(uuid, text) FuncExpr carrying cert.
static Var * make_provenance_attribute (const constants_t *constants, Query *q, RangeTblEntry *r, Index relid, AttrNumber attid)
 Build a Var node that references the provenance column of a relation.
static Node * reduce_varattno_mutator (Node *node, void *ctx)
 Tree-mutator callback that adjusts Var attribute numbers.
static void reduce_varattno_by_offset (List *targetList, Index varno, int *offset)
 Adjust Var attribute numbers in targetList after columns are removed.
static bool is_target_agg_var (Node *node, aggregation_type_mutator_context *context)
 Check if a Var matches the target aggregate column.
static Node * aggregation_type_mutator (Node *node, void *ctx)
 Tree-mutator that retypes a specific Var to agg_token.
static void fix_type_of_aggregation_result (const constants_t *constants, Query *q, Index rteid, List *targetList)
 Retypes aggregation-result Vars in q from UUID to agg_token.
static Query * lookup_lowered_cte (List *lowered, const char *name)
static void inline_ctes_in_rtable (List *rtable, List *cteList, List **lowered)
 Inline CTE references as subqueries within a query.
static void inline_ctes (Query *q)
 Inline all CTE references in q as subqueries.
static List * get_provenance_attributes (const constants_t *constants, Query *q, bool in_boolean_rewrite, const InvFreeMarkerCtx *inv_ctx)
 Collect all provenance Var nodes reachable from q's range table.
static Bitmapset * remove_provenance_attributes_select (const constants_t *constants, Query *q, bool **removed)
 Strip provenance UUID columns from q's SELECT list.
static List * strip_given_markers (const constants_t *constants, Query *q)
 Strip given(evidence) whole-tuple conditioning markers from the visible projection, returning the captured evidence expressions.
static Expr * add_eq_from_OpExpr_to_Expr (const constants_t *constants, OpExpr *fromOpExpr, Expr *toExpr, int **columns)
 Wrap toExpr in a provenance_eq gate if fromOpExpr is an equality between two tracked columns.
static Expr * add_eq_from_Quals_to_Expr (const constants_t *constants, Node *quals, Expr *result, int **columns)
 Walk a join-condition or WHERE quals node and add eq gates for every equality it contains.
static Expr * combine_prov_atts (const constants_t *constants, List *prov_atts, semiring_operation op)
 Build the per-row provenance token for an aggregate rewrite.
static Expr * make_rv_aggregate_expression (const constants_t *constants, Aggref *agg_ref, List *prov_atts, semiring_operation op)
 Inline rewrite of an RV-returning aggregate into the same aggregate over provenance-wrapped per-row arguments.
static Expr * make_aggregation_expression (const constants_t *constants, Aggref *agg_ref, List *prov_atts, semiring_operation op, bool is_scalar)
 Build the provenance expression for a single aggregate function.
static FuncExpr * having_Expr_to_provenance_cmp (Expr *expr, const constants_t *constants, bool negated)
 Dispatch a HAVING sub-expression to the appropriate converter.
static bool needs_having_lift (Node *havingQual, const constants_t *constants)
 Return true if havingQual contains anything the HAVING-lift path needs to handle (an agg_token Var or a provenance_aggregate wrapper).
static Node * normalize_bool_agg_having (Node *n)
static Node * peel_agg_casts (Node *n)
 Peel implicit/explicit cast FuncExprs and RelabelTypes that wrap a single argument, returning the underlying expression.
static Node * try_swap_agg_arith (OpExpr *op, const constants_t *constants)
 Rebuild an arithmetic operator over an aggregate so the result stays an agg_token (provenance preserved).
static bool expr_contains_rv_cmp (Node *node, const constants_t *constants)
 Test whether an Expr (sub-)tree contains any RV comparison.
static bool contains_agg_walker (Node *node, contains_agg_ctx *ctx)
static bool expr_contains_agg (Node *node, const constants_t *constants)
 Whether an expression subtree references an aggregate (a bare provenance_aggregate call or an agg_token Var).
static bool const_as_double (Node *n, double *out)
 Numeric value of a (possibly cast-wrapped) Const; false if the node is not a non-NULL Const.
static Node * build_binop (const char *op, Node *l, Node *r)
 Build l <op> r, resolving the operator by name.
static OpExpr * normalize_agg_comparison (OpExpr *cmp, const constants_t *constants)
 Fold constant arithmetic over an aggregate into the comparison threshold.
static FuncExpr * having_OpExpr_to_provenance_cmp (OpExpr *opExpr, const constants_t *constants, bool negated)
 Convert a comparison OpExpr on aggregate results into a provenance_cmp gate expression.
static FuncExpr * having_null_filtered_plus (const constants_t *constants, Aggref *base_arr, Node *V, Node *K, NullTestType filter)
 Build "⊕(array_agg(K) FILTER (WHERE V IS [NOT] NULL))" – the per-row provenance over just the value rows (filter = IS_NOT_NULL) or just the null-valued rows (filter = IS_NULL) of an aggregate's group.
static FuncExpr * having_NullTest_to_provenance (NullTest *nt, const constants_t *constants, bool negated)
 Convert a NullTest on an aggregate (agg IS [NOT] NULL) into a provenance expression.
static FuncExpr * make_regular_indicator (const constants_t *constants, Expr *expr, bool negated)
 Build the deterministic indicator gate for an ordinary (regular) comparison: regular_indicator(cond) (gate_one when cond holds, gate_zero otherwise).
static FuncExpr * having_BoolExpr_to_provenance (BoolExpr *be, const constants_t *constants, bool negated)
 Convert a Boolean combination of HAVING comparisons into a provenance_times / provenance_plus gate expression.
static int rv_cmp_index (const constants_t *constants, Oid funcoid)
 Test whether funcoid is one of the random_variable_* comparison procedures, and if so return its ComparisonOperator index.
static Expr * wrap_random_variable_uuid (Node *operand, const constants_t *constants)
 Wrap an expression returning random_variable in a binary-coercible cast to uuid.
static FuncExpr * rv_Expr_to_provenance (Expr *expr, const constants_t *constants, bool negated)
 Dispatch a WHERE sub-expression to the appropriate RV converter.
static FuncExpr * rv_OpExpr_to_provenance_cmp (OpExpr *opExpr, const constants_t *constants, bool negated)
 Convert a single RV-comparison OpExpr into a provenance_cmp() FuncExpr returning UUID.
static FuncExpr * rv_BoolExpr_to_provenance (BoolExpr *be, const constants_t *constants, bool negated)
 Convert a Boolean combination of RV comparisons into a provenance_times / provenance_plus expression.
static bool expr_has_probabilistic_cmp (Node *node, void *data)
 Walker: does node contain a probabilistic (random_variable or aggregate) comparison?
static FuncExpr * predicate_to_condition_gate (Expr *expr, const constants_t *constants, bool negated)
 Convert a Boolean predicate into a provenance condition gate.
static bool cond_predicate_target (const constants_t *constants, Oid opfuncid, Oid *cond_fn, Oid *result_type, bool *is_prefix)
 Carrier-routing for an "X | (predicate)" placeholder OpExpr.
static Node * rewrite_cond_predicate_mutator (Node *node, void *data)
 Mutator: rewrite "X | (predicate)" into the carrier's cond.
static void rewrite_cond_predicates (const constants_t *constants, Query *q)
 Rewrite every "X | (predicate)" in q's own clauses.
static bool check_expr_on_rv (Expr *expr, const constants_t *constants)
 Test whether expr is a Boolean combination of only random_variable comparisons (no other leaves allowed).
static Expr * build_joint_width_provenance_expr (const constants_t *constants, const char *desc, Expr *fallback)
 Build the ucq_joint_provenance(descriptor) call substituted for a recognised unsafe UCQ's existence provenance.
static Expr * build_mobius_provenance_expr (const constants_t *constants, const char *desc, Expr *fallback)
 Build the ucq_mobius_provenance(descriptor, fallback) call.
static Expr * build_joint_width_answer_expr (const constants_t *constants, const char *desc, List *head_var_idx, List *head_exprs, Expr *fallback)
 Build the per-answer ucq_joint_provenance_answer(...) call for a recognised non-Boolean UCQ (head variables exposed in the output).
static Expr * build_mobius_answer_expr (const constants_t *constants, const char *desc, List *head_var_idx, List *head_exprs, Expr *fallback)
 Build the per-answer ucq_mobius_provenance_answer(...) call, identical in shape to build_joint_width_answer_expr but for the Möbius route.
static Expr * wrap_mobius_or_null (const constants_t *constants, Expr *mobius_call)
 Wrap a Möbius call in mobius_or_null(...): the token if it roots a gate_mobius (a Möbius success), else NULL (a Möbius decline returns the lineage, never a gate_mobius).
static Expr * combine_safe_routes (const constants_t *constants, Expr *mobius_call, Expr *joint_call, Expr *lineage)
 Combine the Möbius and joint-width routes under Möbius precedence.
static Expr * make_provenance_expression (const constants_t *constants, Query *q, List *prov_atts, bool aggregation, bool group_by_rewrite, semiring_operation op, int **columns, int nbcols, bool wrap_assumed, bool in_boolean_rewrite, const char *inv_cert)
 Build the combined provenance expression to be added to the SELECT list.
static bool provenance_function_walker (Node *node, void *data)
 Tree walker that returns true if any provenance() call is found.
static Query * build_inner_for_distinct_key (Query *q, Expr *key_expr, List *groupby_tes)
 Build the inner GROUP-BY subquery for one AGG(DISTINCT key).
static Query * build_outer_for_distinct_key (TargetEntry *orig_agg_te, Query *inner, int n_gb, const constants_t *constants)
 Wrap inner in an outer query that applies the original aggregate.
static bool collect_having_distinct_walker (Node *node, void *ctx)
 Walker that collects AGG(DISTINCT) Aggrefs from an expression.
static Node * replace_having_distinct_mutator (Node *node, void *ctx)
 Mutator that replaces each AGG(DISTINCT) Aggref in a HAVING clause with Var(next_rtindex++, 1) – the deduped count column of its outer subquery (built in the same order by rewrite_agg_distinct).
static Query * rewrite_agg_distinct (Query *q, const constants_t *constants)
 Rewrite every AGG(DISTINCT key) in q using independent subqueries.
static Node * aggregation_mutator (Node *node, void *ctx)
 Tree-mutator that replaces Aggrefs with provenance-aware aggregates.
static Node * wrap_agg_token_with_cast (FuncExpr *prov_agg, const constants_t *constants)
 Wrap a provenance_aggregate FuncExpr with a cast to the original aggregate return type.
static Node * cast_agg_token_to_type (Node *arg, Oid target_type, const constants_t *constants)
 Wrap an agg_token expression in a cast to target_type.
static void maybe_cast_agg_token_args (List *args, Oid parent_funcid, const constants_t *constants)
 Cast provenance_aggregate arguments of an operator or function when the formal parameter type requires it.
static Node * cast_agg_token_mutator (Node *node, void *ctx)
 Tree-mutator that casts provenance_aggregate results back to the original aggregate return type where needed.
static Node * try_push_into_aggref (OpExpr *op, const constants_t *constants)
 Push distributive constant arithmetic into an aggregate's argument.
static Node * push_arith_into_agg_mutator (Node *node, void *ctx)
 Tree-mutator applying try_push_into_aggref bottom-up.
static void replace_aggregations_by_provenance_aggregate (const constants_t *constants, Query *q, List *prov_atts, semiring_operation op)
 Replace every Aggref in q with a provenance-aware aggregate.
static void add_to_select (Query *q, Expr *provenance)
 Append the provenance expression to q's target list.
static bool expr_contains_aggref_walker (Node *node, void *context)
 expression_tree_walker predicate: returns true on the first Aggref it encounters.
static Node * provenance_mutator (Node *node, void *ctx)
 Tree-mutator that replaces provenance() calls with the actual provenance expression.
static void replace_provenance_function_by_expression (const constants_t *constants, Query *q, Expr *provsql)
 Replace every explicit provenance() call in q with provsql.
static void transform_distinct_into_group_by (Query *q)
 Convert a SELECT DISTINCT into an equivalent GROUP BY.
static void normalize_distinct_into_group_by (Query *q)
 Normalise a supported SELECT DISTINCT into a GROUP BY.
static void remove_provenance_attribute_groupref (Query *q, const Bitmapset *removed_sortgrouprefs)
 Remove sort/group references that belonged to removed provenance columns.
static void remove_provenance_attribute_setoperations (Query *q, bool *removed)
 Strip the provenance column's type info from a set-operation node.
static Query * rewrite_non_all_into_external_group_by (Query *q)
 Wrap a non-ALL set operation in an outer GROUP BY query.
static bool provenance_function_in_group_by (const constants_t *constants, Query *q)
 Check whether a provenance() call appears in the GROUP BY list.
static bool has_rv_or_provenance_call (Node *node, void *data)
 Tree walker that detects any provenance-bearing relation or provenance() call.
static bool is_inert_subselect (Query *q)
 Is q a recorded inert provenance()-fetch subselect?
static bool sublink_is_inert (SubLink *sl)
 Does sl wrap a recorded inert provenance()-fetch subselect?
static bool subselect_is_pure_provenance_fetch (const constants_t *constants, Query *sub)
 Whether sub's sole non-junk output is a bare provenance() call.
static bool inert_fetch_sublink_walker (Node *node, void *data)
 Walker: set found if an inert provenance()-fetch SubLink is present in this query's own clauses (not descending into other scopes).
static bool query_has_inert_fetch (const constants_t *constants, Query *q)
 Does q's own target list / jointree / HAVING contain an inert provenance()-fetch SubLink?
static bool decorr_value_sublink_walker (Node *node, void *data)
static bool has_provenance_walker (Node *node, void *data)
static bool has_provenance (const constants_t *constants, Query *q)
 Return true if q involves any provenance-bearing relation or contains an explicit provenance() call.
static bool sublink_over_tracked_walker (Node *node, void *cx)
 Walker: set found if a SubLink whose subselect (transitively) involves a provenance-tracked relation is reached.
static bool query_has_tracked_sublink (const constants_t *constants, Query *q)
 Does any SubLink in q's own clauses have a subselect that (transitively) involves a provenance-tracked relation?
static void collect_direct_qual_sublinks (Node *node, List **out)
 Collect SubLink nodes sitting in a "direct", decorrelatable position: a target-list entry that is the sublink, or a WHERE/HAVING boolean factor or a direct operand of a comparison.
static bool sublink_classify_walker (Node *node, void *cx)
 Walker classifying each tracked SubLink of a query as either a still-unsupported direct form or an arithmetic-nested one.
static List * classify_remaining_sublinks (const constants_t *constants, Query *q, bool *has_direct)
 Partition q's remaining tracked sublinks into unsupported-direct vs arithmetic-nested.
static bool calls_provenance_walker (Node *node, void *data)
 Walker: true if node (descending through nested queries) contains an explicit provenance() call.
static bool provenance_in_sublink_walker (Node *node, void *data)
 Walker: true if a SubLink subselect calls provenance().
static void remove_provsql_from_select (Query *q)
 Remove the auto-added provsql output column from a rewritten query.
static bool aggtoken_walker (Node *node, void *data)
 Tree walker that detects any Var of type agg_token.
static bool has_aggtoken (Node *node, const constants_t *constants)
 Return true if node contains a Var of type agg_token.
static bool having_lift_walker (Node *node, void *data)
 Walker for needs_having_lift: detect any operand shape that the HAVING-lift rewriter (having_OpExpr_to_provenance_cmp) needs to handle specially.
static bool is_supported_bool_agg (Oid aggfnoid)
static bool transform_except_into_join (const constants_t *constants, Query *q)
 Rewrite an EXCEPT query into a LEFT JOIN with monus provenance.
static void hide_provsql_colname (RangeTblEntry *rel)
 Rename the provsql column in rel's eref so a later get_provenance_attributes pass does not re-detect rel as a provenance source.
static void oj_collect_cols (const constants_t *constants, RangeTblEntry *rel, oj_cols *out)
 Collect the user columns (skipping provsql and dropped columns) of an outer-join arm: a base relation or a subquery.
static bool oj_rte_has_provsql (const constants_t *constants, RangeTblEntry *rel)
 True if rel contributes provenance: a base relation with a provsql UUID column, or a subquery over tracked relations.
static RangeTblEntry * oj_make_subquery_rte (Query *sub)
 Wrap a constructed Query as an RTE_SUBQUERY, building its eref->colnames from the (non-junk) target list.
static RangeTblEntry * oj_copy_rel (Query *outer, Query *sub, RangeTblEntry *orig)
 Copy an outer-join arm RTE into the range table of subquery sub.
static void oj_neutralize_orphan_arm (RangeTblEntry *rel)
 Neutralise an outer-join arm RTE left orphaned after the lowering so get_provenance_attributes does not re-pick it up as a provenance source: a base relation has its provsql column renamed; a subquery (which would still be processed) is turned into an inert RTE_RESULT.
static Node * oj_renum_mut (Node *node, void *cx)
static Query * oj_build_join_query (const constants_t *constants, Query *outer, RangeTblEntry *R, RangeTblEntry *S, Index R_idx, Index S_idx, oj_cols *Rc, oj_cols *Sc, Node *theta, bool select_r, bool select_s)
 Build the inner-join scan subquery "SELECT [R.cols][, S.cols] FROM R JOIN S ON θ".
static Query * oj_build_rel_query (const constants_t *constants, Query *outer, RangeTblEntry *R, oj_cols *Rc)
 Build the plain-scan subquery "SELECT R.cols FROM R".
static Query * oj_build_diff (const constants_t *constants, Query *outer, RangeTblEntry *R, RangeTblEntry *S, Index R_idx, Index S_idx, oj_cols *Rc, oj_cols *Sc, Node *theta, bool keep_left)
 Build the difference subquery for the kept side of an outer join: "SELECT X.cols FROM X EXCEPT ALL SELECT X.cols FROM R JOIN S ON θ", where X = R when keep_left, else S.
static Query * oj_build_antijoin (const constants_t *constants, Query *outer, RangeTblEntry *R, RangeTblEntry *S, Index R_idx, Index S_idx, oj_cols *Rc, oj_cols *Sc, Node *theta, bool keep_left)
 Build a null-padded antijoin arm in R-then-S column order.
static void oj_build_coltype_lists (oj_cols *Rc, oj_cols *Sc, List **types, List **typmods, List **collations)
 Build the column-type lists (R-then-S, user columns only) shared by every set-operation node of the replacement union.
static Query * oj_build_union (const constants_t *constants, Query *outer, RangeTblEntry *R, RangeTblEntry *S, Index R_idx, Index S_idx, oj_cols *Rc, oj_cols *Sc, Node *theta, JoinType jointype)
 Build the UNION-ALL of the matched arm and the outer join's antijoin arm(s): the full outer-join relation in R-then-S column order with one combined provsql column.
static bool oj_joinref_walker (Node *node, void *cx)
static bool oj_refs_join_index (Query *q, Index join_idx)
 True if any outer Var references the join RTE directly (USING / whole-row / alias.col references the conservative remap cannot resolve through joinaliasvars yet).
static Node * oj_outer_remap (Node *node, void *cx)
static bool lower_outer_joins (const constants_t *constants, Query *q)
 Lower a top-level outer JOIN of two base relations into the UNION-ALL of its matched and null-padded antijoin arms.
static Node * oj_decorr_var_mut (Node *node, void *cx)
static bool oj_sublink_scan_walker (Node *node, void *cx)
static Node * oj_sl_replace_mut (Node *node, void *cx)
static bool oj_contains_sublink_walker (Node *node, void *cx)
 Walker: true if the subtree contains the specific SubLink cx.
static Aggref * oj_make_aggref (Oid aggfnoid, Oid aggtype, Oid argtype, Expr *arg)
 Build an Aggref for a single-argument aggregate.
static OpExpr * oj_count_cmp (Var *found_var, Index q_idx, const char *opstr, int64 n)
 Build "count(Q.key) <op> n" over the decorrelated LEFT-JOIN group.
static OpExpr * oj_count_distinct_cmp (Expr *valexpr, const char *opstr, int64 n)
 Build "count(DISTINCT v) <op> n" -- the at-most-one-DISTINCT-value gate of a "SELECT DISTINCT v" body (NULLs, on the null-padded antijoin rows, are ignored by count, so an empty group counts 0).
static Node * oj_wrap_remap_mut (Node *node, void *cx)
static bool oj_wrap_outer_from (const constants_t *constants, Query *q, SubLink *sl, bool in_where)
 Wrap a non-single-relation outer FROM into a derived subquery R' so a scalar subquery can be decorrelated onto it.
static bool predicate_subselect_decorrelatable (const constants_t *constants, Query *sub, bool corr_supplied)
 Is sub a subselect that the predicate-sublink rewrite can turn into a correlated "SELECT count(*) FROM Q WHERE corr"?
static Node * build_count_predicate (Query *subselect, Node *extra_corr, bool antijoin)
 Turn a predicate subselect into the boolean "(SELECT count(*) FROM Q WHERE corr) >= 1" (semijoin) or "... = 0" (antijoin).
static Node * oj_param_repl_mut (Node *node, void *cx)
 Replace every PARAM_SUBLINK with paramid by replacement.
static bool oj_body_has_tracked_relation (const constants_t *constants, Query *body)
 Does the body's range table reach at least one provenance-tracked relation?
static bool normalize_quantified_aggregate_sublinks (const constants_t *constants, Query *q)
 Normalize quantified comparisons over a single bare-aggregate body into plain scalar comparisons.
static Node * extract_quantified_corr (SubLink *sl, bool *antijoin)
 Build the per-row correlation for a quantified sublink (IN / op ANY / op ALL), setting *antijoin.
static bool rewrite_predicate_sublinks (const constants_t *constants, Query *q)
 Rewrite top-level EXISTS / IN WHERE conjuncts (optionally negated) over a single tracked relation into correlated count(*) comparisons.
static bool rewrite_array_sublinks (const constants_t *constants, Query *q)
 Rewrite a top-level ARRAY(SELECT Q.col FROM Q WHERE corr) target-list entry into the aggregate body (SELECT array_agg(Q.col) FROM Q WHERE corr).
static bool oj_wrap_body_from (const constants_t *constants, Query *sub)
 Collapse a multi-table scalar-subquery body FROM into one derived cross-product subquery D, so the decorrelation can treat the body as "SELECT val FROM D WHERE W" with D a single tracked subquery.
static Query * oj_build_uncorrelated_from_subquery (const constants_t *constants, Query *body)
 Build the derived single-row aggregate D for an UNcorrelated scalar subquery body, to be cross-joined into the outer FROM.
static bool oj_uncorrelated_body_over_tracked (const constants_t *constants, Query *sub)
 Is sub an uncorrelated clean SELECT over tracked base relations (a comma-join is fine)?
static Aggref * oj_make_count_star (void)
 A fresh count(*) Aggref (returns int8).
static Query * oj_having_gated_subquery (Query *body, Node *pred)
 Build the one-row "SELECT 1 FROM <body FROM> HAVING <pred>" gated subquery: body supplies the FROM (and any uncorrelated WHERE), pred the aggregate comparison that becomes its provenance.
static bool move_uncorrelated_where_predicates (const constants_t *constants, Query *q)
 Handle UNcorrelated EXISTS and uncorrelated aggregate comparisons in WHERE by cross-joining a HAVING-gated one-row subquery.
static OpExpr * oj_count_const_cmp (Oid opno, Oid inputcollid, Aggref *cnt, Node *constarg)
 Build the "<cnt> <op> const" OpExpr for an antijoin's HAVING, where cnt is a count aggregate (count(*) or count(col)).
static bool oj_zero_satisfies (Oid opno, Const *c)
 Does 0 satisfy the int8 comparison "0 <opno> c"?
static bool rewrite_uncorrelated_antijoin (const constants_t *constants, Query *q)
 Rewrite an uncorrelated WHERE predicate that is satisfied by the empty group – NOT EXISTS, or "(SELECT count(*) FROM Q) <op> const" with "0 <op> const" true (e.g.
static bool move_uncorrelated_sublinks_to_from (const constants_t *constants, Query *q)
 Move uncorrelated scalar subqueries that are direct target-list entries into a cross-joined derived aggregate in the outer FROM.
static bool oj_limit_count_is_one (Node *limitCount)
 Is limitCount the literal 1?
static bool oj_rtables_coalescible (List *rta, List *rtb)
 Can two scalar-subquery bodies share a single decorrelating LEFT JOIN?
static bool oj_sub_bodies_coalescible (Query *a, Query *b)
static bool decorrelate_scalar_sublinks (const constants_t *constants, Query *q)
 Decorrelate a single top-level scalar subquery into a LEFT JOIN.
static void group_set_difference_right_arm (const constants_t *constants, Query *q)
 Group the right-hand arm of a set difference by all its columns so the per-tuple right provenances ⊕-combine before the monus.
static void process_set_operation_union (const constants_t *constants, SetOperationStmt *stmt, Query *q)
 Recursively annotate a UNION tree with the provenance UUID type.
static void add_select_non_zero (const constants_t *constants, Query *q, Expr *provsql)
 Add a WHERE condition filtering out zero-provenance tuples.
static Node * add_to_havingQual (Node *havingQual, Expr *expr)
 Append expr to havingQual with an AND, creating one if needed.
static bool check_selection_on_aggregate (OpExpr *op, const constants_t *constants)
 Check whether op is a supported comparison on an aggregate result.
static bool check_boolexpr_on_aggregate (BoolExpr *be, const constants_t *constants)
 Check whether every leaf of a Boolean expression is a supported comparison on an aggregate result.
static bool check_expr_on_aggregate (Expr *expr, const constants_t *constants)
 Top-level dispatcher for supported WHERE-on-aggregate patterns.
static void build_column_map (Query *q, int **columns, int *nbcols)
 Build the per-RTE column-numbering map used by where-provenance.
static qual_class classify_qual (Expr *expr, const constants_t *constants)
 Classify expr along the qual_class axis.
static void error_for_mixed_qual (qual_class c)
 Raise the user-facing error appropriate to a mixed c.
static List * migrate_probabilistic_quals (const constants_t *constants, Query *q)
 Unified WHERE classifier – routes each top-level conjunct to the right evaluation site in a single pass.
static Oid get_agg_token_orig_type (Var *v, insert_agg_token_casts_context *ctx)
 Look up the original aggregate return type for an agg_token Var.
static void cast_agg_token_in_list (ListCell *lc, insert_agg_token_casts_context *ctx)
 Wrap an agg_token Var in a cast to its original type, in place.
static void cast_agg_token_args (List *args, insert_agg_token_casts_context *ctx)
 Wrap any agg_token Vars in an argument list.
static Node * insert_agg_token_casts_mutator (Node *node, void *data)
 Insert agg_token casts for Vars used in expressions.
static void insert_agg_token_casts (const constants_t *constants, Query *q)
 Walk query and insert agg_token casts where needed.
static bool join_qual_has_agg_token_walker (Node *node, join_qual_agg_token_ctx *ctx)
static bool join_qual_has_agg_token (Node *node, const constants_t *constants, Index *rteid, AttrNumber *join_attno)
 Return true if node contains an OpExpr that equates an agg_token Var with a non-agg_token Var.
static Node * make_uuid_array_subscript (Node *arr_expr, int index, const constants_t *constants)
 Build an AST node for arr[idx] on a uuid[] expression.
static bool retype_agg_var_walker (Node *node, retype_agg_var_ctx *ctx)
 Walker that retypes agg_token Vars to text and rewrites the equality OpExpr to text = text with the non-agg side cast via I/O.
static Query * rewrite_join_agg_token (Query *q, const constants_t *constants, Index rteid, AttrNumber join_attno)
 Replace the source relation of an agg_token JOIN with an explode-style subquery.
static Expr * wrap_in_cond (const constants_t *constants, Expr *target, Expr *evidence)
 Wrap target in a provsql.cond(uuid, uuid) FuncExpr conditioning it on evidence.
static void mark_col_selected (Query *q, RangeTblEntry *r, AttrNumber attno)
 Mark column attno of RTE r as selected (read permission).
static Var * make_column_var (Query *q, RangeTblEntry *r, Index relid, AttrNumber attno)
 A Var for column attno of RTE relid, with the column's actual type/typmod/collation, marking the column selected.
static Expr * coerce_via_io_to_text (Expr *arg)
 Coerce arg to text via its output function (any type -> text).
static Expr * build_inversion_free_marker (const constants_t *constants, Query *q, Var *prov_var, const InvFreeMarker *m)
 Wrap an atom's provenance Var in the inversion-free per-input order marker: annotate(prov, inversion_free_key(root, sec, factor)).
static void wrap_inversion_free_markers (const constants_t *constants, Query *q, List *prov_atts, const InvFreeMarker *markers, int natoms)
 Replace each certified atom's provenance Var in prov_atts with its per-input-marker-wrapped form (in place).
static Node * flatten_mut (Node *node, void *cp)
 Tree mutator implementing the conjunctive inlining of SPJ subqueries.
static FlatAtomOriginflat_origin1 (int slot)
 A depth-1 origin path [slot].
static FlatAtomOriginflat_origin_prepend (int slot, const FlatAtomOrigin *sub)
 Prepend slot to sub's path, for an atom inlined one level up.
static FlatAtomOriginflatten_spj_subqueries (Query *probe, int *nflat_out)
 In place, inline every SPJ subquery/view of probe into its base relations, flattening to one conjunction of base atoms.
static InvFreeMarkerCtxbuild_inversion_free_ctx (const constants_t *constants, Query *q, char **cert_out)
 Build the inversion-free marker context for top-level query q.
static void keep_only_provenance_output (Query *sub)
 Make a processed inert subselect return exactly its provenance token as a single column.
static bool process_inert_fetches_walker (Node *node, void *cx)
static void process_inert_fetches (const constants_t *constants, Query *q)
static void process_insert_select (const constants_t *constants, Query *q)
 Propagate provenance through INSERT ... SELECT.
static bool query_defines_handmade_provsql (Node *node, void *cx)
 Walker: true if any Query in the tree defines a provsql column by hand.
static PlannedStmt * provsql_planner (Query *q, int cursorOptions, ParamListInfo boundParams)
 PostgreSQL planner hook – entry point for provenance rewriting.
static void provsql_executor_start (QueryDesc *queryDesc, int eflags)
static void provsql_executor_end (QueryDesc *queryDesc)
static void provsql_ProcessUtility_capture (Node *parsetree, ProvSQLCtasCapture *cap)
 Decide whether parsetree is a CTAS that should trigger the ancestry hook, and if so populate cap with the inner classification, the (single) source's block-key columns, and the transitive ancestor union.
static const char * provsql_ctas_kind_label (provsql_table_kind k)
 Map provsql_table_kind to its textual label (set_table_info accepts text).
Datum set_table_info (PG_FUNCTION_ARGS)
 Forward declaration of the C SQL entry points.
Datum set_ancestors (PG_FUNCTION_ARGS)
 PostgreSQL-callable wrapper for setTableAncestry() over the IPC pipe.
static void provsql_ProcessUtility_apply (Node *parsetree, ProvSQLCtasCapture *cap)
 Apply cap to the freshly-created relation stmt->into->rel.
static void provsql_ProcessUtility (PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, char *completionTag)

Variables

 PG_MODULE_MAGIC
 Required PostgreSQL extension magic block.
bool provsql_interrupted = false
 Global variable that becomes true if this particular backend received an interrupt signal.
static bool provsql_active = true
 true while ProvSQL query rewriting is enabled
bool provsql_where_provenance = false
 Global variable that indicates if where-provenance support has been activated through the provsql.where_provenance run-time configuration parameter.
static bool provsql_update_provenance = false
 true when provenance tracking for DML is enabled
int provsql_verbose = 100
 Verbosity level; controlled by the provsql.verbose_level GUC.
char * provsql_last_eval_method = NULL
 Last probability evaluation method(s) used; exposed via provsql.last_eval_method.
bool provsql_aggtoken_text_as_uuid = false
 When true, agg_token::text emits the underlying provenance UUID instead of "value (*)".
char * provsql_tool_search_path = NULL
 Colon-separated directory list prepended to PATH when invoking external tools (d4, c2d, minic2d, dsharp, weightmc, graph-easy); controlled by the provsql.tool_search_path GUC. Superuser-only (PGC_SUSET): it dictates which directories the postgres OS user searches for executables, so a non-privileged role must not be able to point it at an attacker-controlled binary.
char * provsql_fallback_compiler = NULL
 Compiler used by BooleanCircuit::makeDD as the final fallback after interpretAsDD and tree-decomposition both fail; controlled by the provsql.fallback_compiler GUC (default "d4").
char * provsql_kcmcp_server = NULL
 Launch command for the managed KCMCP server (with a {endpoint} placeholder); controlled by the provsql.kcmcp_server GUC. Empty means no managed server is launched.
int provsql_monte_carlo_seed = -1
 Seed for the Monte Carlo sampler; -1 means non-deterministic (std::random_device); controlled by the provsql.monte_carlo_seed GUC.
int provsql_rv_mc_samples = 10000
 Default sample count for analytical-evaluator MC fallbacks; 0 disables fallback (callers raise instead); controlled by the provsql.rv_mc_samples GUC.
int provsql_dtree_max_subproblems = 0
 Debug/safety hard cap on d-tree subproblems before it bails (0 = off; the chooser auto-budgets at the next-best method's cost regardless); provsql.dtree_max_subproblems GUC.
int provsql_joint_max_treewidth = 10
 Maximum joint treewidth the joint-width UCQ compiler attempts before declining (caller falls back to the ladder); provsql.joint_max_treewidth GUC.
int provsql_joint_max_states = 65536
 Per-bag DP state-count cap of the joint-width UCQ compiler (the true safety net); provsql.joint_max_states GUC.
bool provsql_joint_width = true
 Recognise unsafe UCQs at planner time and route their existence provenance through the joint-width compiler (on by default); the provsql.joint_width GUC is a debug-only switch to disable it.
bool provsql_mobius = true
 Try the safe-UCQ Möbius-inversion route (a guaranteed-PTIME exact route for its class) BEFORE the joint-width compiler, which it short-circuits on success (on by default); the provsql.mobius GUC is a debug-only switch to disable it.
int provsql_mobius_max_gates = 4000000
 Data-cost cap of the Möbius route: it declines (falling through to joint-width / the ladder) once its compile has built more than this many gates, bounding the \(O(|D|^k)\) blow-up of a high-level safe query on large data; provsql.mobius_max_gates GUC.
bool provsql_simplify_on_load = true
 Run universal cmp-resolution passes when getGenericCircuit returns; controlled by the provsql.simplify_on_load GUC.
bool provsql_hybrid_evaluation = true
 Run the hybrid-evaluator simplifier inside probability_evaluate; controlled by the provsql.hybrid_evaluation GUC.
bool provsql_cmp_probability_evaluation = true
 Run closed-form / analytic probability evaluators for gate_cmps inside probability_evaluate (currently the Poisson-binomial pre-pass for HAVING-COUNT; future MIN / MAX / SUM evaluators will gate on the same GUC); controlled by the provsql.cmp_probability_evaluation GUC.
bool provsql_inversion_free = true
 Insert the inversion-free structured-d-DNNF path into the default probability chain (after independent, when a certificate is present); controlled by the provsql.inversion_free GUC.
bool provsql_boolean_provenance = false
 Derived flag: the session's provenance class is 'boolean' – enables the Boolean-only machinery (safe-query read-once rewrite, Boolean circuit simplifications), whose outputs are tagged so that semiring evaluations admitting no homomorphism from Boolean functions refuse to run on them. Set from the provsql.provenance GUC.
bool provsql_absorptive_provenance = false
 Derived flag: the session's provenance class is 'absorptive' or 'boolean' – licenses constructions sound for absorptive semirings only (cyclic recursive queries stopped at the absorptive value fixpoint, the bounded-treewidth reachability route's certified circuits, absorptive circuit simplifications; tokens tagged accordingly). Set from the provsql.provenance GUC.
static int provsql_provenance_class = PROVSQL_PROVENANCE_SEMIRING
 Backing variable of the provsql.provenance GUC.
static const struct config_enum_entry provsql_provenance_options []
 Option table of the provsql.provenance GUC.
static planner_hook_type prev_planner = NULL
 Previous planner hook (chained).
static List * provsql_inert_subselects = NIL
 Walker (this query level only): true if an EXPR_SUBLINK whose body is a decorrelatable value subquery over a provenance-tracked base relation appears in an expression.
static int provsql_executor_depth = 0
 Executor nesting depth.
static ExecutorStart_hook_type prev_ExecutorStart = NULL
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL
static ProcessUtility_hook_type prev_ProcessUtility = NULL

Detailed Description

PostgreSQL planner hook for transparent provenance tracking.

This file installs a planner_hook that intercepts every SELECT query and rewrites it to propagate a provenance circuit token (UUID) alongside normal result tuples. The rewriting proceeds in three conceptual phases:

  1. Discovery – scan the range table for relations/subqueries that already carry a provsql UUID column (get_provenance_attributes).
  2. Expression building – combine the discovered tokens according to the semiring operation that corresponds to the SQL operator in use (⊗ for joins, ⊕ for duplicate elimination, ⊖ for EXCEPT) and wrap aggregations (make_provenance_expression, make_aggregation_expression).
  3. Splice – append the resulting provenance expression to the target list and replace any explicit provenance() call in the query with the computed expression (add_to_select, replace_provenance_function_by_expression).

Definition in file provsql.c.

Enumeration Type Documentation

◆ provsql_provenance_class_t

Values of the provsql.provenance enum GUC, from most general to most specialised.

Enumerator
PROVSQL_PROVENANCE_WHERE 

Universal semiring provenance plus where-provenance gates.

PROVSQL_PROVENANCE_SEMIRING 

Universal semiring provenance (default).

PROVSQL_PROVENANCE_ABSORPTIVE 

Absorptive-semiring constructions licensed (tagged).

PROVSQL_PROVENANCE_BOOLEAN 

Boolean-only machinery licensed (tagged); implies absorptive.

Definition at line 111 of file provsql.c.

◆ qual_class

enum qual_class

Categorisation of a top-level WHERE conjunct.

Drives the unified WHERE classifier. Both probabilistic flavours (agg_token's "moved to HAVING" world and random_variable's "lifted to provenance" world) are special cases of "this conjunct involves a probabilistic value the executor cannot evaluate as a Boolean directly, so the planner has to route it to a different evaluation site". The classifier reports which site, or (for unsupported mixes) errors.

Enumerator
QUAL_DETERMINISTIC 

no probabilistic value; stays in WHERE

QUAL_PURE_AGG 

pure agg_token expression; route to HAVING

QUAL_PURE_RV 

pure random_variable expression; lift to provenance

QUAL_MIXED_AGG_DET 

agg_token mixed with non-agg leaves; error

QUAL_MIXED_RV_DET 

random_variable mixed with non-RV leaves; error

QUAL_MIXED_AGG_RV 

agg_token and random_variable in the same expr; error

Definition at line 10412 of file provsql.c.

◆ semiring_operation

Semiring operation used to combine provenance tokens.

SR_TIMES corresponds to the multiplicative operation (joins, Cartesian products), SR_PLUS to the additive operation (duplicate elimination), and SR_MONUS to the monus / set-difference operation (EXCEPT).

See also
https://provsql.org/lean-docs/Provenance/QueryRewriting.html Lean 4 formalization of rewriting rules (R1)–(R5) and correctness theorem Query.rewriting_valid.
Enumerator
SR_PLUS 

Semiring addition (UNION, SELECT DISTINCT).

SR_MONUS 

Semiring monus / set difference (EXCEPT).

SR_TIMES 

Semiring multiplication (JOIN, Cartesian product).

Definition at line 2308 of file provsql.c.

Function Documentation

◆ _PG_fini()

void _PG_fini ( void )
extern

Extension teardown – restores the planner and shmem hooks.

Definition at line 13973 of file provsql.c.

◆ _PG_init()

void _PG_init ( void )
extern

Extension initialization – called once when the shared library is loaded.

Registers the GUC variables (provsql.active, where_provenance, update_provenance, verbose_level, aggtoken_text_as_uuid, tool_search_path), installs the planner hook and shared-memory hooks, and launches the background MMap worker.

Must be loaded via shared_preload_libraries; raises an error otherwise.

Definition at line 13472 of file provsql.c.

Here is the call graph for this function:

◆ add_eq_from_OpExpr_to_Expr()

Expr * add_eq_from_OpExpr_to_Expr ( const constants_t * constants,
OpExpr * fromOpExpr,
Expr * toExpr,
int ** columns )
static

Wrap toExpr in a provenance_eq gate if fromOpExpr is an equality between two tracked columns.

Used for where-provenance: each equijoin condition (and some WHERE equalities) introduces an eq gate that records which attribute positions were compared. Because this function is also called for WHERE predicates, it applies extra guards and silently returns toExpr unchanged when the expression does not match the expected shape (both sides must be Var nodes, possibly wrapped in a RelabelType).

Parameters
constantsExtension OID cache.
fromOpExprThe equality OpExpr to inspect.
toExprExisting provenance expression to wrap.
columnsPer-RTE column-numbering array. EQ gate positions carry the same sequential-number caveat as PROJECT gate positions (see build_column_map()); they are only correct when each operand's RTE is either a join RTE or a subquery, not a bare provenance-tracked base table.
Returns
toExpr wrapped in provenance_eq(toExpr, col1, col2), or toExpr unchanged if the shape is unsupported.

Definition at line 2341 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_eq_from_Quals_to_Expr()

Expr * add_eq_from_Quals_to_Expr ( const constants_t * constants,
Node * quals,
Expr * result,
int ** columns )
static

Walk a join-condition or WHERE quals node and add eq gates for every equality it contains.

Dispatches to add_eq_from_OpExpr_to_Expr for simple OpExpr nodes and iterates over the arguments of an AND BoolExpr. OR/NOT inside a join ON clause are rejected with an error.

Parameters
constantsExtension OID cache.
qualsRoot of the quals tree (OpExpr or BoolExpr), or NULL (in which case result is returned unchanged).
resultProvenance expression to wrap.
columnsPer-RTE column-numbering array.
Returns
Updated provenance expression with zero or more eq gates added.

Definition at line 2417 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_select_non_zero()

void add_select_non_zero ( const constants_t * constants,
Query * q,
Expr * provsql )
static

Add a WHERE condition filtering out zero-provenance tuples.

For EXCEPT queries, tuples whose provenance evaluates to zero (i.e., the right-hand side fully subsumes the left-hand side) must be excluded from the result. This function appends provsql <> gate_zero() to q->jointree->quals, ANDing with any existing WHERE condition.

Parameters
constantsExtension OID cache.
qQuery to modify in place.
provsqlProvenance expression that was added to the SELECT list.

Definition at line 10186 of file provsql.c.

Here is the caller graph for this function:

◆ add_to_havingQual()

Node * add_to_havingQual ( Node * havingQual,
Expr * expr )
static

Append expr to havingQual with an AND, creating one if needed.

If havingQual is NULL, returns expr directly. If it is already an AND BoolExpr, appends to its argument list. Otherwise wraps both in a new AND node.

Parameters
havingQualExisting HAVING qualifier, or NULL.
exprExpression to conjoin.
Returns
The updated HAVING qualifier.

Definition at line 10223 of file provsql.c.

Here is the caller graph for this function:

◆ add_to_select()

void add_to_select ( Query * q,
Expr * provenance )
static

Append the provenance expression to q's target list.

Inserts a new TargetEntry named provsql immediately before any resjunk entries (which must remain last) and adjusts the resno of subsequent entries accordingly.

Parameters
qQuery to modify in place.
provenanceExpression to add (becomes the provsql output column).

Definition at line 5738 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ aggregation_mutator()

Node * aggregation_mutator ( Node * node,
void * ctx )
static

Tree-mutator that replaces Aggrefs with provenance-aware aggregates.

Parameters
nodeCurrent expression tree node.
ctxPointer to an aggregation_mutator_context (prov_atts, op, and constants).
Returns
Possibly modified node.

Definition at line 5290 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ aggregation_type_mutator()

Node * aggregation_type_mutator ( Node * node,
void * ctx )
static

Tree-mutator that retypes a specific Var to agg_token.

When the target Var is inside a cast FuncExpr, replaces the cast function with the equivalent agg_token→target cast from pg_cast. When the Var appears bare (e.g. in a TargetEntry for display), it is retyped to agg_token directly. In all other contexts (arithmetic, window functions, etc.), wraps the Var in an explicit agg_token→original cast so that parent nodes receive the expected type.

Parameters
nodeCurrent expression tree node.
ctxPointer to an aggregation_type_mutator_context (varno, varattno, and constants).
Returns
Possibly modified node.

Definition at line 295 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ aggtoken_walker()

bool aggtoken_walker ( Node * node,
void * data )
static

Tree walker that detects any Var of type agg_token.

Parameters
nodeCurrent expression tree node.
dataPointer to a constants_t (extension OID cache).
Returns
true if an agg_token Var is found in node.

Definition at line 6768 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_binop()

Node * build_binop ( const char * op,
Node * l,
Node * r )
static

Build l <op> r, resolving the operator by name.

Definition at line 2841 of file provsql.c.

Here is the caller graph for this function:

◆ build_column_map()

void build_column_map ( Query * q,
int ** columns,
int * nbcols )
static

Build the per-RTE column-numbering map used by where-provenance.

Assigns a sequential position (1, 2, 3, …) to every non-provenance, non-join, non-empty column across all RTEs in q->rtable. The provsql column is assigned -1 so callers can detect provenance-tracked RTEs. Join-RTE columns and empty-named columns (used for anonymous GROUP BY keys) are assigned 0.

Note
For RTE_RELATION entries that are provenance-tracked, the sequential numbers produced here must not be used as PROJECT gate positions. Because numbering is query-order-dependent, the sequential number for a column of a provenance table that is not the first RTE will exceed nb_columns of that table's IN gate, causing WhereCircuit::evaluate() to return an empty locator set. Instead, callers should use varattno directly (see make_provenance_expression()). The -1 sentinel is the reliable way to identify a provenance-tracked RTE.
Parameters
qQuery whose range table is mapped.
columnsPre-allocated array of length q->rtable->length. Each element is allocated and filled by this function.
nbcolsOut-param: total number of non-provenance output columns.

Definition at line 10360 of file provsql.c.

Here is the caller graph for this function:

◆ build_count_predicate()

Node * build_count_predicate ( Query * subselect,
Node * extra_corr,
bool antijoin )
static

Turn a predicate subselect into the boolean "(SELECT count(*) FROM Q WHERE corr) >= 1" (semijoin) or "... = 0" (antijoin).

EXISTS / IN are existence tests ("⊕Q present"), so they are exactly "count(*) >= 1"; NOT EXISTS / NOT IN are their antijoin duals, "count(*) = 0". Lowering them to a correlated count() comparison lets the aggregate-body arm of decorrelate_scalar_sublinks do the rest: it rewrites count(*) to count(Q.key) over the "R ⟕ Q" group (so the null-padded antijoin row is not counted) and lifts the comparison into HAVING – i.e. the semijoin R⊗⊕Q and the antijoin R⊗(1⊖⊕Q) fall out of the existing outer-join lowering.

extra_corr (for IN / NOT IN) is the "Q.col = x" correlation lifted out of the testexpr; it is ANDed into the subselect's WHERE. EXISTS passes NULL, its correlation already living in the subselect.

Definition at line 8346 of file provsql.c.

Here is the caller graph for this function:

◆ build_inner_for_distinct_key()

Query * build_inner_for_distinct_key ( Query * q,
Expr * key_expr,
List * groupby_tes )
static

Build the inner GROUP-BY subquery for one AGG(DISTINCT key).

Produces:

SELECT key_expr, gb_col1, gb_col2, ...
FROM <same tables as q>
GROUP BY key_expr, gb_col1, gb_col2, ...
Parameters
qOriginal query (supplies FROM / WHERE).
key_exprThe DISTINCT argument expression.
groupby_tesNon-aggregate target entries that are GROUP BY columns.
Returns
Fresh inner Query.

Definition at line 4785 of file provsql.c.

Here is the caller graph for this function:

◆ build_inversion_free_ctx()

InvFreeMarkerCtx * build_inversion_free_ctx ( const constants_t * constants,
Query * q,
char ** cert_out )
static

Build the inversion-free marker context for top-level query q.

Runs the detector on a flattened, group-RTE-stripped copy of q so that single-base SPJ subqueries/views are recognised as base atoms. On success sets *cert_out to the serialised root certificate and returns a context tree mirroring q's range table: a direct base atom's marker at its slot, a flattened subquery's marker in a one-entry child context at its slot. Returns NULL (declining) when q is not certified or carries no markers; *cert_out may still be set (the cert attaches even without markers, and the path then declines at evaluation and falls back).

Definition at line 11878 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_inversion_free_marker()

Expr * build_inversion_free_marker ( const constants_t * constants,
Query * q,
Var * prov_var,
const InvFreeMarker * m )
static

Wrap an atom's provenance Var in the inversion-free per-input order marker: annotate(prov, inversion_free_key(root, sec, factor)).

prov_var is a Var on the atom's provsql column (its varno is the range-table index of the atom); m gives the root- and secondary-class columns and the factor for that atom.

Definition at line 11482 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_joint_width_answer_expr()

Expr * build_joint_width_answer_expr ( const constants_t * constants,
const char * desc,
List * head_var_idx,
List * head_exprs,
Expr * fallback )
static

Build the per-answer ucq_joint_provenance_answer(...) call for a recognised non-Boolean UCQ (head variables exposed in the output).

Per output group the head variables are bound to their values; the substituted call materialises the head-pinned certified d-D for that answer (head_vals is ARRAY[head Vars], evaluated per group at execution). fallback (the normal per-answer provenance) is returned on any decline. Heads are int4 Vars (the recogniser's restriction), so the value array is a plain int4[]. Returns NULL if the function cannot be resolved or there are no heads.

Definition at line 4001 of file provsql.c.

Here is the caller graph for this function:

◆ build_joint_width_provenance_expr()

Expr * build_joint_width_provenance_expr ( const constants_t * constants,
const char * desc,
Expr * fallback )
static

Build the ucq_joint_provenance(descriptor) call substituted for a recognised unsafe UCQ's existence provenance.

The descriptor (built by provsql_joint_width_descriptor from the query's syntax) is wrapped as a jsonb Const; the resulting provenance token is the joint-width compiler's certified d-D, so the standard probability / Shapley evaluators answer the #P-hard UCQ through the one pipeline. Returns NULL if the function cannot be resolved (e.g. an older schema without it), leaving the normal path.

Definition at line 3913 of file provsql.c.

Here is the caller graph for this function:

◆ build_mobius_answer_expr()

Expr * build_mobius_answer_expr ( const constants_t * constants,
const char * desc,
List * head_var_idx,
List * head_exprs,
Expr * fallback )
static

Build the per-answer ucq_mobius_provenance_answer(...) call, identical in shape to build_joint_width_answer_expr but for the Möbius route.

Wired as the runtime fallback of the joint-width per-answer call, so the joint-width single-DP keeps priority and the Möbius head-pinned compile runs only on its decline. Returns fallback if the function cannot be resolved.

Definition at line 4074 of file provsql.c.

Here is the caller graph for this function:

◆ build_mobius_provenance_expr()

Expr * build_mobius_provenance_expr ( const constants_t * constants,
const char * desc,
Expr * fallback )
static

Build the ucq_mobius_provenance(descriptor, fallback) call.

The Möbius-inversion route (safe-UCQ Möbius cancellation, the last missing exact route of the Dalvi-Suciu dichotomy) shares the joint-width descriptor. It is wired as the runtime fallback of the joint-width call (see make_provenance_expression): the joint-width compiler is tried first (strict priority – it is more general on its inputs), and only on its decline (e.g. the joint treewidth exceeds the cap, as for q9 on adversarial data) does the Möbius compiler run; on its own decline the fallback (the normal provenance) is returned, so the query never fails. Returns NULL if the function cannot be resolved (older schema), leaving fallback.

Definition at line 3959 of file provsql.c.

Here is the caller graph for this function:

◆ build_outer_for_distinct_key()

Query * build_outer_for_distinct_key ( TargetEntry * orig_agg_te,
Query * inner,
int n_gb,
const constants_t * constants )
static

Wrap inner in an outer query that applies the original aggregate.

Produces:

SELECT AGG(key_col), gb_col1, gb_col2, ...
FROM inner
GROUP BY gb_col1, gb_col2, ...

The DISTINCT flag is cleared; inner provides exactly one row per (key, group-by) combination, so the plain aggregate gives the right count.

Parameters
orig_agg_teOriginal TargetEntry containing AGG(DISTINCT key).
innerInner query from build_inner_for_distinct_key.
n_gbNumber of GROUP BY columns (trailing entries in inner).
constantsExtension OID cache.
Returns
Fresh outer Query.

Definition at line 4855 of file provsql.c.

Here is the caller graph for this function:

◆ calls_provenance_walker()

bool calls_provenance_walker ( Node * node,
void * data )
static

Walker: true if node (descending through nested queries) contains an explicit provenance() call.

Definition at line 6677 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cast_agg_token_args()

void cast_agg_token_args ( List * args,
insert_agg_token_casts_context * ctx )
static

Wrap any agg_token Vars in an argument list.

Definition at line 10684 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cast_agg_token_in_list()

void cast_agg_token_in_list ( ListCell * lc,
insert_agg_token_casts_context * ctx )
static

Wrap an agg_token Var in a cast to its original type, in place.

Definition at line 10650 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cast_agg_token_mutator()

Node * cast_agg_token_mutator ( Node * node,
void * ctx )
static

Tree-mutator that casts provenance_aggregate results back to the original aggregate return type where needed.

After the aggregation mutator replaces Aggrefs with provenance_aggregate calls (returning agg_token), this post-processing step inserts casts where the surrounding expression expects a different type (e.g. a non-arithmetic function over an aggregate). Arithmetic over an aggregate is instead kept as an agg_token via try_swap_agg_arith so its provenance survives; arguments to functions that accept agg_token or polymorphic types are left alone.

Parameters
nodeCurrent expression tree node.
ctxPointer to the constants_t OID cache.
Returns
Possibly modified node.

Definition at line 5536 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cast_agg_token_to_type()

Node * cast_agg_token_to_type ( Node * arg,
Oid target_type,
const constants_t * constants )
static

Wrap an agg_token expression in a cast to target_type.

Companion to wrap_agg_token_with_cast for agg_token values that are not a bare provenance_aggregate call (e.g. the result of agg_token arithmetic): the original aggregate type is not recoverable from the node, so we cast to the type the consuming context requires.

Definition at line 5348 of file provsql.c.

Here is the caller graph for this function:

◆ check_boolexpr_on_aggregate()

bool check_boolexpr_on_aggregate ( BoolExpr * be,
const constants_t * constants )
static

Check whether every leaf of a Boolean expression is a supported comparison on an aggregate result.

Recursively validates OpExpr leaves via check_selection_on_aggregate and descends into nested BoolExpr nodes.

Parameters
beThe Boolean expression to validate.
constantsExtension OID cache.
Returns
True if all leaves are supported, false if any is not.

Definition at line 10289 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_expr_on_aggregate()

bool check_expr_on_aggregate ( Expr * expr,
const constants_t * constants )
static

Top-level dispatcher for supported WHERE-on-aggregate patterns.

Parameters
exprExpression to validate (OpExpr or BoolExpr).
constantsExtension OID cache.
Returns
True if ProvSQL can handle this expression.

Definition at line 10321 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_expr_on_rv()

bool check_expr_on_rv ( Expr * expr,
const constants_t * constants )
static

Test whether expr is a Boolean combination of only random_variable comparisons (no other leaves allowed).

Mirrors check_expr_on_aggregate / check_boolexpr_on_aggregate for the agg_token WHERE-to-HAVING migration path. Recursively accepts:

  • BoolExpr (AND/OR/NOT) all of whose children pass; and
  • OpExpr matching one of the random_variable_* comparators.

Anything else (a non-RV OpExpr, a Var, a Const, a non-cmp FuncExpr) makes the expression mixed and unsupportable by the RV-only walker, so the function returns false and the caller raises a clear error.

Definition at line 3873 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_selection_on_aggregate()

bool check_selection_on_aggregate ( OpExpr * op,
const constants_t * constants )
static

Check whether op is a supported comparison on an aggregate result.

Returns true iff op is a two-argument operator where at least one argument is a Var of type agg_token (or an implicit-cast wrapper thereof) and the other is a Const (possibly cast). This is the set of WHERE-on-aggregate patterns that ProvSQL can safely move to a HAVING clause.

Parameters
opThe OpExpr to inspect.
constantsExtension OID cache.
Returns
True if the pattern is supported, false otherwise.

Definition at line 10256 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ classify_qual()

qual_class classify_qual ( Expr * expr,
const constants_t * constants )
static

Classify expr along the qual_class axis.

Decision table (the predicates has_aggtoken, expr_contains_rv_cmp, check_expr_on_aggregate, and check_expr_on_rv each return whether the expression "contains" or "is purely" the corresponding flavour):

aggtoken rv_cmp check_agg check_rv classification
yes yes - - QUAL_MIXED_AGG_RV
yes no true - QUAL_PURE_AGG
yes no false - QUAL_MIXED_AGG_DET
no yes - true QUAL_PURE_RV
no yes - false QUAL_MIXED_RV_DET
no no - - QUAL_DETERMINISTIC

Definition at line 10438 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ classify_remaining_sublinks()

List * classify_remaining_sublinks ( const constants_t * constants,
Query * q,
bool * has_direct )
static

Partition q's remaining tracked sublinks into unsupported-direct vs arithmetic-nested.

Returns the list of nested SubLink nodes (for warnings) and sets *has_direct if any unsupported direct form remains.

Definition at line 6640 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ coerce_via_io_to_text()

Expr * coerce_via_io_to_text ( Expr * arg)
static

Coerce arg to text via its output function (any type -> text).

Definition at line 11464 of file provsql.c.

Here is the caller graph for this function:

◆ collect_direct_qual_sublinks()

void collect_direct_qual_sublinks ( Node * node,
List ** out )
static

Collect SubLink nodes sitting in a "direct", decorrelatable position: a target-list entry that is the sublink, or a WHERE/HAVING boolean factor or a direct operand of a comparison.

These are exactly the positions the rewrite passes (rewrite_predicate_sublinks, decorrelate_scalar_sublinks…) consume. A tracked sublink still in such a position after those passes is a genuinely unsupported direct form (a GROUP BY body, a multi-relation EXISTS…) that must raise the clean error. A tracked sublink anywhere else is nested inside an expression (arithmetic, a function argument); those are let through with a warning instead – Postgres evaluates the sublink normally (correct value), the row keeps the outer relation's provenance, and the subquery's data is treated as certain.

Definition at line 6569 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ collect_having_distinct_walker()

bool collect_having_distinct_walker ( Node * node,
void * ctx )
static

Walker that collects AGG(DISTINCT) Aggrefs from an expression.

Does not descend into an Aggref's own arguments, so the traversal order matches replace_having_distinct_mutator below (both stop at every Aggref), keeping the per-aggregate outer-subquery indices aligned.

Definition at line 4960 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ combine_prov_atts()

Expr * combine_prov_atts ( const constants_t * constants,
List * prov_atts,
semiring_operation op )
static

Build the per-row provenance token for an aggregate rewrite.

Used by both make_aggregation_expression (for the agg_token / provenance_semimod path) and make_rv_aggregate_expression (for the inline RV-aggregate path). Combines prov_atts via provenance_times (under SR_TIMES) or provenance_monus (under SR_MONUS); a single prov_att is returned as-is.

Returns
An Expr returning UUID; never NULL.

Definition at line 2460 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ combine_safe_routes()

Expr * combine_safe_routes ( const constants_t * constants,
Expr * mobius_call,
Expr * joint_call,
Expr * lineage )
static

Combine the Möbius and joint-width routes under Möbius precedence.

Builds COALESCE(mobius_or_null(mobius), joint) – a SHORT-CIRCUITING choice: the safe-UCQ Möbius cancellation route (a guaranteed PTIME \(O(|D|^k)\) exact route for its class – TID, self-join-free, safe) is tried first; on success it roots a gate_mobius and COALESCE returns it without ever evaluating – hence ever running – the joint-width compiler. Only when Möbius declines (correlated inputs, self-joins, or an unsafe shape: mobius_or_null then yields NULL) does the joint-width compiler run, with the literal lineage as its own fallback. Möbius is preferred not because joint-width is provably worse – whether the Möbius class has bounded joint treewidth is open (no polynomial d-D is known for q9, but none is proved impossible for the general d-D class either) – but because Möbius is a guaranteed-terminating route for its class whereas the joint-width compiler may grind to its state cap before declining. mobius_call / joint_call are pre-built route expressions (either may be NULL when its debug GUC is off); lineage is the normal provenance, the final fallback.

Definition at line 4183 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cond_predicate_target()

bool cond_predicate_target ( const constants_t * constants,
Oid opfuncid,
Oid * cond_fn,
Oid * result_type,
bool * is_prefix )
static

Carrier-routing for an "X | (predicate)" placeholder OpExpr.

Maps the placeholder's opfuncid to the conditioning constructor to emit and its result type; the prefix whole-tuple form (given_predicate) maps to given, whose single argument is the gate (no left operand). Returns false if opfuncid is not a conditioning placeholder.

Definition at line 3727 of file provsql.c.

Here is the caller graph for this function:

◆ const_as_double()

bool const_as_double ( Node * n,
double * out )
static

Numeric value of a (possibly cast-wrapped) Const; false if the node is not a non-NULL Const.

Definition at line 2823 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ contains_agg_walker()

bool contains_agg_walker ( Node * node,
contains_agg_ctx * ctx )
static

Definition at line 2796 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decorr_value_sublink_walker()

bool decorr_value_sublink_walker ( Node * node,
void * data )
static

Definition at line 6337 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decorrelate_scalar_sublinks()

bool decorrelate_scalar_sublinks ( const constants_t * constants,
Query * q )
static

Decorrelate a single top-level scalar subquery into a LEFT JOIN.

Restricted (v1) to: a CMD_SELECT whose FROM is a single tracked base relation R, with exactly one SubLink in the whole query, that SubLink being an EXPR_SUBLINK that is the direct expression of a target-list entry, whose body is "SELECT val FROM Q [WHERE corr]" over a single base relation Q referencing only Q (level 0) and R (level 1). Returns true if the query was rewritten in place.

Definition at line 9522 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ error_for_mixed_qual()

void error_for_mixed_qual ( qual_class c)
static

Raise the user-facing error appropriate to a mixed c.

Each provsql_error call is ereport(ERROR), which does not return; the explicit break statements below are present only to keep -Wimplicit-fallthrough happy (PostgreSQL's elog macro is not marked noreturn for the compiler's flow analysis).

Definition at line 10464 of file provsql.c.

Here is the caller graph for this function:

◆ expr_contains_agg()

bool expr_contains_agg ( Node * node,
const constants_t * constants )
static

Whether an expression subtree references an aggregate (a bare provenance_aggregate call or an agg_token Var).

Definition at line 2815 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ expr_contains_aggref_walker()

bool expr_contains_aggref_walker ( Node * node,
void * context )
static

expression_tree_walker predicate: returns true on the first Aggref it encounters.

Used to decide whether the provenance expression about to be substituted would inject a nested aggregate when a provenance() call lives inside another Aggref's argument tree.

Definition at line 5801 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ expr_contains_rv_cmp()

bool expr_contains_rv_cmp ( Node * node,
const constants_t * constants )
static

Test whether an Expr (sub-)tree contains any RV comparison.

Used by the WHERE-clause extractor to decide whether a top-level conjunct mentions any random_variable comparator and therefore needs lifting (or, if the conjunct mixes RV and non-RV operators in a way we cannot rewrite, errors).

Definition at line 3836 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ expr_has_probabilistic_cmp()

bool expr_has_probabilistic_cmp ( Node * node,
void * data )
static

Walker: does node contain a probabilistic (random_variable or aggregate) comparison?

Distinguishes a conditioning predicate (which has at least one such comparison) from a purely-regular one (an ordinary filter, which is NOT a conditioning event and is rejected by the "X | (predicate)" rewrite).

Definition at line 3615 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_quantified_corr()

Node * extract_quantified_corr ( SubLink * sl,
bool * antijoin )
static

Build the per-row correlation for a quantified sublink (IN / op ANY / op ALL), setting *antijoin.

The testexpr is "x op Param(subselect output)" (single column), or -- for a row IN -- a BoolExpr AND of per-column "xᵢ = Paramᵢ". For each we copy the op, sink the outer operand one level, and substitute the subselect's paramid-th output column for the PARAM_SUBLINK placeholder, keeping any coercions (e.g. a varchar->text relabel) intact. ANY is a semijoin (*antijoin = false, operator kept); ALL is the universal dual, the antijoin (*antijoin = true, operator negated – "∀q. x op q" = "¬∃q. x ¬op q"). Returns NULL for unsupported shapes (a RowCompareExpr, a multi-column ALL, a bad paramid…).

Definition at line 8533 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fix_type_of_aggregation_result()

void fix_type_of_aggregation_result ( const constants_t * constants,
Query * q,
Index rteid,
List * targetList )
static

Retypes aggregation-result Vars in q from UUID to agg_token.

After a subquery that contains provenance_aggregate is processed, its result type is agg_token rather than plain UUID. This mutator walks the outer query and updates the type of every Var referencing that result column so that subsequent type-checking passes correctly.

Parameters
constantsExtension OID cache.
qOuter query to patch.
rteidRange-table index of the subquery in q.
targetListTarget list of the subquery (to locate provenance_aggregate columns).

Definition at line 350 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ flat_origin1()

FlatAtomOrigin * flat_origin1 ( int slot)
static

A depth-1 origin path [slot].

Definition at line 11629 of file provsql.c.

Here is the caller graph for this function:

◆ flat_origin_prepend()

FlatAtomOrigin * flat_origin_prepend ( int slot,
const FlatAtomOrigin * sub )
static

Prepend slot to sub's path, for an atom inlined one level up.

Definition at line 11638 of file provsql.c.

Here is the caller graph for this function:

◆ flatten_mut()

Node * flatten_mut ( Node * node,
void * cp )
static

Tree mutator implementing the conjunctive inlining of SPJ subqueries.

Parent mode (quals_mode false): a Var on an inlined subquery slot is replaced by the base Var its target list maps the column to, renumbered to that base's new flat position; a Var on a kept slot is renumbered to the slot's new position. Subquery-WHERE mode (quals_mode true): a base Var inside subquery quals_slot is renumbered to its new flat position. Outer references (varlevelsup > 0) are never touched.

Definition at line 11590 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ flatten_spj_subqueries()

FlatAtomOrigin * flatten_spj_subqueries ( Query * probe,
int * nflat_out )
static

In place, inline every SPJ subquery/view of probe into its base relations, flattening to one conjunction of base atoms.

A range-table slot is inlined when it is a non-lateral RTE_SUBQUERY whose subquery is a plain SELECT (no aggregation, grouping, DISTINCT, set operation, sublink, CTE or LIMIT), whose FROM is flat RangeTblRefs over base RTE_RELATIONs (PG 14/15 view OLD/NEW placeholders ignored; one or more bases – a view with a join inside is fine), and whose non-junk target list entries are all plain Vars on those bases. Such a subquery is a pure SPJ over base relations: its bases are appended in place of the slot, the parent's column references are substituted by the corresponding base columns, and the subquery's WHERE is pulled up, yielding an equivalent flat conjunction. The parent's own FROM must already be flat RangeTblRefs (the detector requires this too); an explicit JoinExpr there carries ON-conditions a fromlist rebuild would drop, so flattening is declined.

Parameters
probethe (throwaway) query copy to flatten in place.
nflat_outset to the flattened range-table length.
Returns
a palloc'd FlatAtomOrigin per flattened position, mapping it back to the parent slot (and, for an inlined subquery, the base position within it) so the detector's per-atom markers can be threaded to the right input.

Definition at line 11675 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_agg_token_orig_type()

Oid get_agg_token_orig_type ( Var * v,
insert_agg_token_casts_context * ctx )
static

Look up the original aggregate return type for an agg_token Var.

Navigates from the Var's varno/varattno to the subquery's target list, finds the provenance_aggregate() FuncExpr, and extracts the type OID from its second argument (aggtype).

Definition at line 10622 of file provsql.c.

Here is the caller graph for this function:

◆ get_provenance_attributes()

List * get_provenance_attributes ( const constants_t * constants,
Query * q,
bool in_boolean_rewrite,
const InvFreeMarkerCtx * inv_ctx )
static

Collect all provenance Var nodes reachable from q's range table.

Walks every RTE in q->rtable:

  • RTE_RELATION: looks for a column named provsql of type UUID.
  • RTE_SUBQUERY: recursively calls process_query and splices the resulting provenance column back into the parent's column list, also patching outer Var attribute numbers if inner columns were removed.
  • RTE_CTE: non-recursive CTEs are inlined as RTE_SUBQUERY before the main loop, then processed as above. Recursive CTEs raise an error.
  • RTE_FUNCTION: handled when the function returns a single UUID column named provsql.
  • RTE_JOIN / RTE_VALUES / RTE_GROUP: handled passively (the underlying base-table RTEs supply the tokens).
Parameters
constantsExtension OID cache.
qQuery whose range table is scanned (subquery RTEs are modified in place by the recursive call).
in_boolean_rewriteTrue when q lies under a safe-query (boolean) rewrite; threaded into the subquery recursion so the joint-width recogniser defers throughout the subtree.
inv_ctxInversion-free marker context for q, or NULL; its per-subquery child context is threaded into each recursive process_query call so a flattened view's base inputs receive their order markers.
Returns
List of Var nodes, one per provenance source; NIL if the query has no provenance-bearing relation.

Definition at line 1985 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ group_set_difference_right_arm()

void group_set_difference_right_arm ( const constants_t * constants,
Query * q )
static

Group the right-hand arm of a set difference by all its columns so the per-tuple right provenances ⊕-combine before the monus.

ProvSQL's multiset difference implements the NOT-IN semantics of the ICDE 2026 paper (§IV-B):

⟪q₁ − q₂⟫ = {{ (u, α ⊖ ⊕_{β : (u,β)∈q₂} β) | (u,α) ∈ q₁ }}

The sum ⊕β ranges over ALL right tuples equal to u, so the right arm must be grouped by its columns first. Without that, transform_except_into_join's bare LEFT JOIN emits one monus per matching right tuple (yielding (α⊖βᵢ) instead of α⊖⊕β) and inflates the result multiplicity – the long-standing "add group by in the right-side table" gap. Wrapping the still-raw right arm in

SELECT cols FROM (rarg) GROUP BY cols

makes the later get_provenance_attributes / group-by pass build ⊕β per group and gives the right arm exactly one row per distinct u.

Runs before provenance discovery, on the SETOP_EXCEPT query (for the non-ALL case, on the all=true inner set operation that rewrite_non_all_into_external_group_by leaves behind). It applies equally to EXCEPT (ε(q₁−q₂)) and EXCEPT ALL (q₁−q₂): the only difference between them, duplicate elimination of the left arm, is handled separately by the non-ALL outer GROUP BY.

Definition at line 10038 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_aggtoken()

bool has_aggtoken ( Node * node,
const constants_t * constants )
static

Return true if node contains a Var of type agg_token.

Used to detect whether a WHERE clause references an aggregate result (which must be moved to HAVING).

Parameters
nodeExpression tree to inspect.
constantsExtension OID cache.
Returns
True if an agg_token Var is found anywhere in node.

Definition at line 6792 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_provenance()

bool has_provenance ( const constants_t * constants,
Query * q )
static

Return true if q involves any provenance-bearing relation or contains an explicit provenance() call.

This is the gate condition checked by provsql_planner before doing any rewriting: if neither condition holds the query is passed through unchanged.

Parameters
constantsExtension OID cache.
qQuery to inspect.
Returns
True if provenance rewriting is needed.

Definition at line 6494 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_provenance_walker()

bool has_provenance_walker ( Node * node,
void * data )
static

Definition at line 6377 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_rv_or_provenance_call()

bool has_rv_or_provenance_call ( Node * node,
void * data )
static

Tree walker that detects any provenance-bearing relation or provenance() call.

Parameters
nodeCurrent expression tree node.
dataPointer to constants_t (cast from void*).
Returns
true if provenance rewriting is needed for this node.

Recursive helper for has_provenance_walker that detects rv_cmp OpExpr and provenance() FuncExpr in expression subtrees.

Stops at Query boundaries: SubLink subselects (used as scalar/array subqueries in expressions) are not rewritten by the outer planner_hook pass, so a tracked relation inside one must not cause the OUTER query's gate to engage. Only the testexpr of a SubLink is followed (it lives in the outer's evaluation scope).

Definition at line 6193 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ having_BoolExpr_to_provenance()

FuncExpr * having_BoolExpr_to_provenance ( BoolExpr * be,
const constants_t * constants,
bool negated )
static

Convert a Boolean combination of HAVING comparisons into a provenance_times / provenance_plus gate expression.

Applies De Morgan duality when negated is true: AND becomes provenance_plus (OR) and vice-versa. NOT is handled by flipping negated and delegating to having_Expr_to_provenance_cmp.

Parameters
beBoolean expression from the HAVING clause.
constantsExtension OID cache.
negatedWhether the expression appears under a NOT.
Returns
A FuncExpr combining the sub-expressions.

Definition at line 3346 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ having_Expr_to_provenance_cmp()

FuncExpr * having_Expr_to_provenance_cmp ( Expr * expr,
const constants_t * constants,
bool negated )
static

Dispatch a HAVING sub-expression to the appropriate converter.

Entry point for the mutual recursion between having_BoolExpr_to_provenance and having_OpExpr_to_provenance_cmp.

Parameters
exprSub-expression to convert (BoolExpr or OpExpr).
constantsExtension OID cache.
negatedWhether the expression appears under a NOT.
Returns
Converted FuncExpr.

Definition at line 3396 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ having_lift_walker()

bool having_lift_walker ( Node * node,
void * data )
static

Walker for needs_having_lift: detect any operand shape that the HAVING-lift rewriter (having_OpExpr_to_provenance_cmp) needs to handle specially.

Returns true on:

  • a Var of type agg_token; or
  • a FuncExpr whose funcid is provenance_aggregate (the wrapper the planner-hook puts around aggregates over tracked non-RV columns – yields agg_token).

Anything else (deterministic scalars, plain Const, FuncExpr over random_variable like expected / variance / moment, comparisons of those) is left for PostgreSQL to evaluate natively; the HAVING-lift never needs to touch it.

Definition at line 6812 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ having_null_filtered_plus()

FuncExpr * having_null_filtered_plus ( const constants_t * constants,
Aggref * base_arr,
Node * V,
Node * K,
NullTestType filter )
static

Build "⊕(array_agg(K) FILTER (WHERE V IS [NOT] NULL))" – the per-row provenance over just the value rows (filter = IS_NOT_NULL) or just the null-valued rows (filter = IS_NULL) of an aggregate's group.

base_arr is the aggregate's array_agg(provenance_semimod(V, K)) Aggref; we copy it, swap its argument to K, and add the FILTER on V (the per-row aggregated value, NULL exactly when the row does not contribute). The filtered array_agg is NULL (not an empty array) for a group with no row of the requested kind, so it is wrapped in COALESCE(..., '{}') – the STRICT provenance_plus then yields gate_zero rather than NULL.

Definition at line 3125 of file provsql.c.

Here is the caller graph for this function:

◆ having_NullTest_to_provenance()

FuncExpr * having_NullTest_to_provenance ( NullTest * nt,
const constants_t * constants,
bool negated )
static

Convert a NullTest on an aggregate (agg IS [NOT] NULL) into a provenance expression.

sum / avg / min / max / array_agg / choose are NULL exactly when no value row contributes (every aggregated value absent or NULL). Split the group's rows into value rows (V IS NOT NULL → tokens Kn, the rows the aggregate is defined over) and null-valued rows (V IS NULL → tokens Kz, present but not contributing). Then:

  • IS NOT NULLδ(⊕Kn): a value row is present.
  • IS NULL, scalar (no GROUP BY) → "1 ⊖ ⊕Kn": the single result row always exists and is NULL exactly when no value row is present.
  • IS NULL, grouped → "δ(⊕Kz) ⊗ (1 ⊖ ⊕Kn)": the group is present via a null-valued row while no value row is present, so the aggregate is NULL. (When the group has no null-valued rows Kz is empty and this collapses to gate_zero, matching the pre-fix behaviour; the all-NULL-valued group, once an unsupported edge, is now handled.)

Splitting on V (not the whole-group ) is what fixes both directions when null-valued rows are present: the old code used over every row, so IS NOT NULL over-counted (a null-only world looked non-NULL) and grouped IS NULL was dropped entirely.

The aggregate must be a direct provenance_aggregate call (an agg_token Var coming from a subquery exposes no token array and is rejected).

Definition at line 3192 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ having_OpExpr_to_provenance_cmp()

FuncExpr * having_OpExpr_to_provenance_cmp ( OpExpr * opExpr,
const constants_t * constants,
bool negated )
static

Convert a comparison OpExpr on aggregate results into a provenance_cmp gate expression.

Each argument of opExpr must be one of:

  • A Var of type agg_token (or a FuncExpr implicit-cast wrapper around one) → cast to UUID via agg_token_to_uuid.
  • A scalar Const, or a bare grouped-column Var (necessarily a GROUP BY key in a HAVING clause, hence constant within each group) → wrapped in provenance_semimod(value, gate_one()).

If negated is true the operator OID is replaced by its negator so that NOT(a < b) becomes a >= b at the provenance level.

Parameters
opExprThe comparison expression from the HAVING clause.
constantsExtension OID cache.
negatedWhether the expression appears under a NOT.
Returns
A provenance_cmp(lhs, op_oid, rhs) FuncExpr.

Definition at line 3009 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hide_provsql_colname()

void hide_provsql_colname ( RangeTblEntry * rel)
static

Rename the provsql column in rel's eref so a later get_provenance_attributes pass does not re-detect rel as a provenance source.

Used when a relation's provenance has already been captured elsewhere – by an explode-style subquery (the aggregation rewrite) or, in the outer-join lowering, by the replacement UNION subquery, leaving the original base relation orphaned in the range table. Renaming only the (unreferenced) eref entry is enough: detection matches on the eref colname.

Definition at line 7129 of file provsql.c.

Here is the caller graph for this function:

◆ inert_fetch_sublink_walker()

bool inert_fetch_sublink_walker ( Node * node,
void * data )
static

Walker: set found if an inert provenance()-fetch SubLink is present in this query's own clauses (not descending into other scopes).

Definition at line 6304 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ inline_ctes()

void inline_ctes ( Query * q)
static

Inline all CTE references in q as subqueries.

Definition at line 1933 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ inline_ctes_in_rtable()

void inline_ctes_in_rtable ( List * rtable,
List * cteList,
List ** lowered )
static

Inline CTE references as subqueries within a query.

Replaces each non-recursive RTE_CTE entry in rtable with an RTE_SUBQUERY containing a copy of the CTE's query, looking up definitions in cteList. Recurses into newly inlined subqueries to handle nested CTE references (ctelevelsup > 0).

Parameters
rtableRange table to scan for RTE_CTE entries.
cteListCTE definitions to look up names in.
loweredIn/out memo of recursive CTEs already lowered (name -> scan subquery), so a recursive CTE referenced more than once is lowered exactly once and later references reuse the first lowering instead of recreating its temp table.

Definition at line 1347 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_agg_token_casts()

void insert_agg_token_casts ( const constants_t * constants,
Query * q )
static

Walk query and insert agg_token casts where needed.

Definition at line 10743 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_agg_token_casts_mutator()

Node * insert_agg_token_casts_mutator ( Node * node,
void * data )
static

Insert agg_token casts for Vars used in expressions.

After the WHERE-to-HAVING migration, agg_token Vars remaining in expression nodes (OpExpr, WindowFunc, CoalesceExpr, MinMaxExpr, etc.) need explicit casts to their original type so that operators and functions receive correct values. The original type is looked up from the provenance_aggregate() call in the subquery.

Definition at line 10704 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_inert_subselect()

bool is_inert_subselect ( Query * q)
static

Is q a recorded inert provenance()-fetch subselect?

Definition at line 6258 of file provsql.c.

Here is the caller graph for this function:

◆ is_supported_bool_agg()

bool is_supported_bool_agg ( Oid aggfnoid)
static

Definition at line 6852 of file provsql.c.

Here is the caller graph for this function:

◆ is_target_agg_var()

bool is_target_agg_var ( Node * node,
aggregation_type_mutator_context * context )
static

Check if a Var matches the target aggregate column.

Definition at line 270 of file provsql.c.

Here is the caller graph for this function:

◆ join_qual_has_agg_token()

bool join_qual_has_agg_token ( Node * node,
const constants_t * constants,
Index * rteid,
AttrNumber * join_attno )
static

Return true if node contains an OpExpr that equates an agg_token Var with a non-agg_token Var.

On a match, writes the agg_token Var's varno and varattno to *rteid and *join_attno. Used to detect JOIN conditions that require the rewrite_join_agg_token rewrite.

Parameters
nodeExpression tree to inspect.
constantsExtension OID cache.
rteidOut: varno of the agg_token Var (unchanged on miss).
join_attnoOut: attno of the agg_token Var (unchanged on miss).
Returns
True iff such an OpExpr was found.

Definition at line 10813 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ join_qual_has_agg_token_walker()

bool join_qual_has_agg_token_walker ( Node * node,
join_qual_agg_token_ctx * ctx )
static

Definition at line 10756 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ keep_only_provenance_output()

void keep_only_provenance_output ( Query * sub)
static

Make a processed inert subselect return exactly its provenance token as a single column.

After process_query (with wrap_root false, so the token is the plain provenance expression, not assume_boolean-wrapped) the subselect carries the resolved provenance() value, an auto-appended provsql column, and possibly resjunk grouping / ordering keys. An inert scalar fetch must return exactly one non-junk column: keep the resolved provenance() value (the first non-junk entry that is not the appended provsql), drop the provsql duplicate, and retain the resjunk entries that GROUP BY / ORDER BY still reference.

Definition at line 12002 of file provsql.c.

Here is the caller graph for this function:

◆ lookup_lowered_cte()

Query * lookup_lowered_cte ( List * lowered,
const char * name )
static

Definition at line 432 of file provsql.c.

Here is the caller graph for this function:

◆ lower_outer_joins()

bool lower_outer_joins ( const constants_t * constants,
Query * q )
static

Lower a top-level outer JOIN of two base relations into the UNION-ALL of its matched and null-padded antijoin arms.

Fires only on jointree->fromlist == [JoinExpr(JOIN_LEFT|JOIN_RIGHT|JOIN_FULL, RTR, RTR)] whose arms are provenance-tracked base relations and where no outer Var references the join RTE directly. Everything else falls through unchanged. Returns true if the query was rewritten.

Definition at line 7762 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_aggregation_expression()

Expr * make_aggregation_expression ( const constants_t * constants,
Aggref * agg_ref,
List * prov_atts,
semiring_operation op,
bool is_scalar )
static

Build the provenance expression for a single aggregate function.

For SR_PLUS (union context) returns the first provenance attribute directly. For SR_TIMES or SR_MONUS, constructs:

provenance_aggregate(fn_oid, result_type,
original_aggref,
array_agg(provenance_semimod(arg, times_or_monus_token)))

COUNT(*) and COUNT(expr) are remapped to SUM so that the semimodule semantics (scalar × token → token) work correctly.

Parameters
constantsExtension OID cache.
agg_refThe original Aggref node from the query.
prov_attsList of provenance Var nodes.
opSemiring operation (determines how tokens are combined).
is_scalarAggregation has no GROUP BY (single always-present row).
Returns
Provenance expression of type agg_token.

Definition at line 2578 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_column_var()

Var * make_column_var ( Query * q,
RangeTblEntry * r,
Index relid,
AttrNumber attno )
static

A Var for column attno of RTE relid, with the column's actual type/typmod/collation, marking the column selected.

Definition at line 11452 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_provenance_attribute()

Var * make_provenance_attribute ( const constants_t * constants,
Query * q,
RangeTblEntry * r,
Index relid,
AttrNumber attid )
static

Build a Var node that references the provenance column of a relation.

Creates a Var pointing to attribute attid of range-table entry relid, typed as UUID, and marks the column as selected in the permission bitmap so PostgreSQL grants access correctly.

Parameters
constantsExtension OID cache.
qOwning query (needed to update permission info on PG 16+).
rRange-table entry that owns the provenance column.
relid1-based index of r in q->rtable.
attid1-based attribute number of the provenance column in r.
Returns
A freshly allocated Var node.

Definition at line 169 of file provsql.c.

Here is the caller graph for this function:

◆ make_provenance_expression()

Expr * make_provenance_expression ( const constants_t * constants,
Query * q,
List * prov_atts,
bool aggregation,
bool group_by_rewrite,
semiring_operation op,
int ** columns,
int nbcols,
bool wrap_assumed,
bool in_boolean_rewrite,
const char * inv_cert )
static

Build the combined provenance expression to be added to the SELECT list.

Combines the tokens in prov_atts according to op:

  • SR_PLUS → use the first token directly (union branch; the outer array_agg / provenance_plus is added later if needed).
  • SR_TIMES → wrap all tokens in provenance_times(...).
  • SR_MONUS → wrap all tokens in provenance_monus(...).

When aggregation or group_by_rewrite is true, wraps the result in array_agg + provenance_plus to collapse groups. A provenance_delta gate is added for plain aggregations without a HAVING clause.

If a HAVING clause is present it is removed from q->havingQual and converted into a provenance expression via having_Expr_to_provenance_cmp.

If provsql_where_provenance is enabled, equality gates (provenance_eq) are prepended for join conditions and WHERE equalities, and a projection gate is appended if the output columns form a proper subset of the input columns.

Parameters
constantsExtension OID cache.
qQuery being rewritten (HAVING is cleared if present).
prov_attsList of provenance Var nodes.
aggregationTrue if the query contains aggregate functions.
group_by_rewriteTrue if a GROUP BY requires the plus-aggregate wrapper.
opSemiring operation to use for combining tokens.
columnsPer-RTE column-numbering array (for where-provenance). For provenance-tracked RTE_RELATION entries, the -1 sentinel is used to identify them; the PROJECT gate positions for their columns use varattno rather than the query-order-dependent sequential numbers (see build_column_map() for the rationale).
nbcolsTotal number of non-provenance output columns.
wrap_assumedIf true, wrap the result in assume_boolean so downstream probability evaluators may treat it as Boolean.
in_boolean_rewriteTrue when this query lies under a safe-query (boolean) rewrite; the joint-width substitution declines so it never pre-empts the read-once form.
inv_certIf non-NULL, a serialised inversion-free certificate to attach to the per-row root via provsql.annotate (transparent for every evaluator; read back by the probability dispatcher). Mutually compatible with wrap_assumed only in principle – the inversion-free path never sets the latter.
Returns
The provenance Expr to be appended to the target list.

Definition at line 4253 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_regular_indicator()

FuncExpr * make_regular_indicator ( const constants_t * constants,
Expr * expr,
bool negated )
static

Build the deterministic indicator gate for an ordinary (regular) comparison: regular_indicator(cond) (gate_one when cond holds, gate_zero otherwise).

Used for the regular leaves of a MIXED predicate (one that also carries a probabilistic comparison), in both the conditioning rewrite and the WHERE / HAVING Boolean analysis – the χ case of the HAVING-provenance semantics. Under negation, χ(¬ψ) = 𝟙 ⊖ χ(ψ): wrap expr in NOT.

Definition at line 3313 of file provsql.c.

Here is the caller graph for this function:

◆ make_rv_aggregate_expression()

Expr * make_rv_aggregate_expression ( const constants_t * constants,
Aggref * agg_ref,
List * prov_atts,
semiring_operation op )
static

Inline rewrite of an RV-returning aggregate into the same aggregate over provenance-wrapped per-row arguments.

Handles any aggregate whose result type is random_variable (e.g. provsql.sum, provsql.avg). Replaces agg(x) with an Aggref whose per-row argument is lifted through rv_aggregate_semimod to attach the row's provenance: each row contributes mixture(prov_token, X_i, as_random(0)). The aggregate itself (aggfnoid) is preserved verbatim, so its SFUNC / FFUNC decide what gate shape to build from the per-row mixtures. In particular:

  • sum(random_variable) collects the mixtures into a single gate_arith PLUS root, realising \(\mathrm{SUM}(x) = \sum_i \mathbf{1}\{\varphi_i\} \cdot X_i\);
  • avg(random_variable) walks each mixture to recover prov_i and emits gate_arith(DIV, sum(mixture(p_i,x_i,0)), sum(mixture(p_i,1,0))), the natural lift of "AVG = SUM / COUNT" into the random_variable algebra.

Routing happens at make_aggregation_expression on agg_ref->aggtype == OID_TYPE_RANDOM_VARIABLE, so any future RV-returning aggregate inherits the same per-row provenance wrap without further C-side dispatch.

SR_PLUS (UNION outer level) is handled by the caller; this builder never runs for SR_PLUS.

Definition at line 2516 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_uuid_array_subscript()

Node * make_uuid_array_subscript ( Node * arr_expr,
int index,
const constants_t * constants )
static

Build an AST node for arr[idx] on a uuid[] expression.

Wraps the version rename between ArrayRef (PG < 12) and SubscriptingRef (PG 12+), and the addition of refrestype (PG 14+).

Parameters
arr_exprExpression evaluating to uuid[].
index1-based element position.
constantsExtension OID cache.
Returns
Subscripting node with result type uuid.

Definition at line 10834 of file provsql.c.

Here is the caller graph for this function:

◆ mark_col_selected()

void mark_col_selected ( Query * q,
RangeTblEntry * r,
AttrNumber attno )
static

Mark column attno of RTE r as selected (read permission).

Definition at line 11436 of file provsql.c.

Here is the caller graph for this function:

◆ maybe_cast_agg_token_args()

void maybe_cast_agg_token_args ( List * args,
Oid parent_funcid,
const constants_t * constants )
static

Cast provenance_aggregate arguments of an operator or function when the formal parameter type requires it.

For each argument in args that is a provenance_aggregate call, check the corresponding formal parameter type of the parent function parent_funcid. If the formal type is polymorphic or agg_token itself, the argument is left alone. Otherwise a cast to the original aggregate return type is inserted.

Parameters
argsArgument list to inspect (modified in place).
parent_funcidOID of the parent function / operator implementor.
constantsExtension OID cache.

Definition at line 5386 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ migrate_probabilistic_quals()

List * migrate_probabilistic_quals ( const constants_t * constants,
Query * q )
static

Unified WHERE classifier – routes each top-level conjunct to the right evaluation site in a single pass.

Walks the WHERE clause, classifies each top-level conjunct, and routes pure-agg_token conjuncts to HAVING and pure-random_variable conjuncts to the returned rv_cmps list, leaving the deterministic conjuncts in WHERE. Doing it in one pass means the rare conjunct that mixes agg_token and random_variable gets a deterministic, useful error message.

Supported shapes:

  • Whole WHERE is a single conjunct: classify and route or error.
  • Top-level AND of conjuncts: classify each, route, and (after walking) collapse the AND if it has zero or one remaining children so downstream code does not see a degenerate Boolean node.
  • Top-level OR / NOT containing both deterministic and probabilistic leaves: error.
Parameters
constantsExtension OID cache.
qQuery whose jointree->quals and havingQual may both be mutated in place.
Returns
List of FuncExpr nodes (one per lifted RV conjunct), each producing a UUID. The caller conjoins these into prov_atts before make_provenance_expression.

Definition at line 10520 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ move_uncorrelated_sublinks_to_from()

bool move_uncorrelated_sublinks_to_from ( const constants_t * constants,
Query * q )
static

Move uncorrelated scalar subqueries that are direct target-list entries into a cross-joined derived aggregate in the outer FROM.

An uncorrelated (SELECT agg/val FROM Q …) is a single constant value: it becomes a one-row derived table D (see oj_build_uncorrelated_from_subquery) appended to the FROM as a cross-join, and the target entry is replaced by a Var to D's column. Restricted to a direct target-list entry so the (aggregate) agg_token flows straight to the output column: nesting it inside arithmetic would coerce the agg_token to a scalar and silently drop its provenance. Runs before decorrelate_scalar_sublinks; correlated sublinks (and ones in other positions) are left untouched for the remaining paths.

Definition at line 9383 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ move_uncorrelated_where_predicates()

bool move_uncorrelated_where_predicates ( const constants_t * constants,
Query * q )
static

Handle UNcorrelated EXISTS and uncorrelated aggregate comparisons in WHERE by cross-joining a HAVING-gated one-row subquery.

EXISTS (SELECT … FROM Q) -> "SELECT 1 FROM Q HAVING count(*) >= 1"; "(SELECT agg(..) FROM Q) OP v" (v not referencing the outer) -> "SELECT 1 FROM Q HAVING agg(..) OP v". The gated D is appended to the FROM, so the conjunct's truth becomes "R ⊗ [predicate]" – ProvSQL's HAVING annotates (the one aggregate row is always materialised, gated), so no actual-instance row is needed. Faithful to ProvSQL aggregates: the empty-Q world drops (so NOT EXISTS, satisfied only by the empty group, is left rejected). Correlated predicates are handled by rewrite_predicate_sublinks.

Definition at line 9060 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ needs_having_lift()

bool needs_having_lift ( Node * havingQual,
const constants_t * constants )
static

Return true if havingQual contains anything the HAVING-lift path needs to handle (an agg_token Var or a provenance_aggregate wrapper).

A qual that returns false is left in place for PostgreSQL to evaluate, while the per-group provenance still gets a gate_delta wrapper.

This is what lets a HAVING like expected(avg(rv)) > 20 work directly: provsql.avg returns random_variable (not agg_token), expected collapses to a scalar double, and the surrounding comparison is a plain Boolean that PostgreSQL can filter groups by without any provenance-side rewriting.

Definition at line 6845 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_agg_comparison()

OpExpr * normalize_agg_comparison ( OpExpr * cmp,
const constants_t * constants )
static

Fold constant arithmetic over an aggregate into the comparison threshold.

Given a comparison OpExpr one of whose sides is an aggregate wrapped in constant arithmetic (the other side being aggregate-free), returns an equivalent "bare_agg <op'> threshold'" OpExpr. Returns NULL when the comparison has no aggregate, has aggregates on both sides (which cannot be folded into a scalar threshold), or uses an arithmetic shape we do not fold (e.g. a constant divided by the aggregate).

Definition at line 2860 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_bool_agg_having()

Node * normalize_bool_agg_having ( Node * n)
static

Definition at line 6869 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_distinct_into_group_by()

void normalize_distinct_into_group_by ( Query * q)
static

Normalise a supported SELECT DISTINCT into a GROUP BY.

Wraps transform_distinct_into_group_by() with the validity guards (DISTINCT ON and DISTINCT-on-aggregate-results stay rejected; a DISTINCT not covering the whole target list is inconsistent).

Called twice on the main rewrite path: once before inline_ctes() so the recursive-reachability detectors see the GROUP BY form (a SELECT DISTINCT region aggregation is provenance-identical to its GROUP BY twin), and once at the late site – idempotent, since the first call clears distinctClause, so the second is a no-op for any query the first already normalised. The target list carries only the user's columns at both call sites (the provsql output column is spliced later), so the length guard reads the same either way.

Parameters
qQuery to normalise in place.

Definition at line 5936 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_quantified_aggregate_sublinks()

bool normalize_quantified_aggregate_sublinks ( const constants_t * constants,
Query * q )
static

Normalize quantified comparisons over a single bare-aggregate body into plain scalar comparisons.

An aggregate body without GROUP BY returns exactly one row, so "x op ANY (SELECT agg(..) …)" and "x op ALL (…)" are the scalar comparison "x op (SELECT agg(..) …)" (NULL semantics included), and a NOT-wrapped form (NOT IN) is the negator-operator comparison. The conjunct's PARAM_SUBLINK placeholder is substituted by the EXPR_SUBLINK body, after which the scalar paths lower it: the HAVING-gated cross-joined subquery for a constant comparand (move_uncorrelated_where_predicates) or the "R ⟕ Q" decorrelation for an outer-column comparand (decorrelate_scalar_sublinks). Runs before rewrite_uncorrelated_antijoin so a normalized count() comparison that is true on the empty body still gets the antijoin treatment there.

Definition at line 8448 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_body_has_tracked_relation()

bool oj_body_has_tracked_relation ( const constants_t * constants,
Query * body )
static

Does the body's range table reach at least one provenance-tracked relation?

Bodies over untracked relations only are left to PostgreSQL's native sublink machinery.

Definition at line 8420 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_antijoin()

Query * oj_build_antijoin ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
RangeTblEntry * S,
Index R_idx,
Index S_idx,
oj_cols * Rc,
oj_cols * Sc,
Node * theta,
bool keep_left )
static

Build a null-padded antijoin arm in R-then-S column order.

For keep_left it emits the left-unmatched rows "SELECT D.cols, NULL,… FROM (R EXCEPT ALL R⋈S) D" (S columns NULL); for the right side it emits "SELECT NULL,…, D.cols FROM (S EXCEPT ALL R⋈S) D" (R columns NULL). The kept side's columns come from the difference D (which also carries the antijoin provenance); the other side is typed NULL constants.

Definition at line 7543 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_coltype_lists()

void oj_build_coltype_lists ( oj_cols * Rc,
oj_cols * Sc,
List ** types,
List ** typmods,
List ** collations )
static

Build the column-type lists (R-then-S, user columns only) shared by every set-operation node of the replacement union.

Definition at line 7591 of file provsql.c.

Here is the caller graph for this function:

◆ oj_build_diff()

Query * oj_build_diff ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
RangeTblEntry * S,
Index R_idx,
Index S_idx,
oj_cols * Rc,
oj_cols * Sc,
Node * theta,
bool keep_left )
static

Build the difference subquery for the kept side of an outer join: "SELECT X.cols FROM X EXCEPT ALL SELECT X.cols FROM R JOIN S ON θ", where X = R when keep_left, else S.

Processed natively as an EXCEPT (→ ProvSQL's −), yielding per distinct kept tuple x the monus provenance X(x) ⊖ ⊕_match (R(r)⊗S(s)) = X(x) ⊗ (1 ⊖ ⊕_match Y(y)) – the null-padded antijoin branch of the join.

Definition at line 7484 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_join_query()

Query * oj_build_join_query ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
RangeTblEntry * S,
Index R_idx,
Index S_idx,
oj_cols * Rc,
oj_cols * Sc,
Node * theta,
bool select_r,
bool select_s )
static

Build the inner-join scan subquery "SELECT [R.cols][, S.cols] FROM R JOIN S ON θ".

Projects R's columns when select_r and S's columns when select_s, in R-then-S order. R is copied at index 1, S at index 2, the synthetic join RTE at index 3; θ is copied and its base-relation varnos remapped (R_idx→1, S_idx→2).

Definition at line 7363 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_rel_query()

Query * oj_build_rel_query ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
oj_cols * Rc )
static

Build the plain-scan subquery "SELECT R.cols FROM R".

Definition at line 7450 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_uncorrelated_from_subquery()

Query * oj_build_uncorrelated_from_subquery ( const constants_t * constants,
Query * body )
static

Build the derived single-row aggregate D for an UNcorrelated scalar subquery body, to be cross-joined into the outer FROM.

Aggregate body "SELECT agg(..) FROM Q [WHERE]" -> D is the body itself (always one row). Value body "SELECT val FROM Q [WHERE]" -> D is "SELECT choose(val) FROM Q [WHERE] HAVING count(*) <= 1" – one row, with the scalar subquery's at-most-one-row rule baked into the moved subquery. Returns NULL unless the body is an uncorrelated clean SELECT over tracked base relations (a comma-join is fine; D is then an inner join).

Faithful to ProvSQL aggregates: an empty Q yields an empty group, hence a gate_zero row that drops out – exactly what a hand-written derived aggregate does; the correlated path's 0-match NULL row is not reconstructed.

Definition at line 8904 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_build_union()

Query * oj_build_union ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
RangeTblEntry * S,
Index R_idx,
Index S_idx,
oj_cols * Rc,
oj_cols * Sc,
Node * theta,
JoinType jointype )
static

Build the UNION-ALL of the matched arm and the outer join's antijoin arm(s): the full outer-join relation in R-then-S column order with one combined provsql column.

jointype selects which null-padded antijoin branches are added: JOIN_LEFT adds the left (R-kept) branch, JOIN_RIGHT the right (S-kept) branch, JOIN_FULL both.

Definition at line 7614 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_collect_cols()

void oj_collect_cols ( const constants_t * constants,
RangeTblEntry * rel,
oj_cols * out )
static

Collect the user columns (skipping provsql and dropped columns) of an outer-join arm: a base relation or a subquery.

For a relation the column attno is its catalog attribute number; for a subquery it is the target entry's resno.

Definition at line 7153 of file provsql.c.

Here is the caller graph for this function:

◆ oj_contains_sublink_walker()

bool oj_contains_sublink_walker ( Node * node,
void * cx )
static

Walker: true if the subtree contains the specific SubLink cx.

Definition at line 7999 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_copy_rel()

RangeTblEntry * oj_copy_rel ( Query * outer,
Query * sub,
RangeTblEntry * orig )
static

Copy an outer-join arm RTE into the range table of subquery sub.

A base relation carries its permission info (PG 16+); a subquery has no direct permissions (its inner query keeps its own rteperminfos).

Definition at line 7276 of file provsql.c.

Here is the caller graph for this function:

◆ oj_count_cmp()

OpExpr * oj_count_cmp ( Var * found_var,
Index q_idx,
const char * opstr,
int64 n )
static

Build "count(Q.key) <op> n" over the decorrelated LEFT-JOIN group.

found_var is some Q column from the correlation (NULL on the null-padded antijoin rows, so it counts only genuine matches); it is re-pointed to the pulled-up Q at q_idx. Used for the scalar-subquery at-most-one-row gate ("<= 1") and the WHERE-comparison non-empty gate (">= 1").

Definition at line 8036 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_count_const_cmp()

OpExpr * oj_count_const_cmp ( Oid opno,
Oid inputcollid,
Aggref * cnt,
Node * constarg )
static

Build the "<cnt> <op> const" OpExpr for an antijoin's HAVING, where cnt is a count aggregate (count(*) or count(col)).

Definition at line 9201 of file provsql.c.

Here is the caller graph for this function:

◆ oj_count_distinct_cmp()

OpExpr * oj_count_distinct_cmp ( Expr * valexpr,
const char * opstr,
int64 n )
static

Build "count(DISTINCT v) <op> n" -- the at-most-one-DISTINCT-value gate of a "SELECT DISTINCT v" body (NULLs, on the null-padded antijoin rows, are ignored by count, so an empty group counts 0).

Definition at line 8065 of file provsql.c.

Here is the caller graph for this function:

◆ oj_decorr_var_mut()

Node * oj_decorr_var_mut ( Node * node,
void * cx )
static

Definition at line 7929 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_having_gated_subquery()

Query * oj_having_gated_subquery ( Query * body,
Node * pred )
static

Build the one-row "SELECT 1 FROM <body FROM> HAVING <pred>" gated subquery: body supplies the FROM (and any uncorrelated WHERE), pred the aggregate comparison that becomes its provenance.

Definition at line 9036 of file provsql.c.

Here is the caller graph for this function:

◆ oj_joinref_walker()

bool oj_joinref_walker ( Node * node,
void * cx )
static

Definition at line 7689 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_limit_count_is_one()

bool oj_limit_count_is_one ( Node * limitCount)
static

Is limitCount the literal 1?

Unwraps the int4->int8 coercion PostgreSQL wraps a "LIMIT 1" literal in.

Definition at line 9442 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_aggref()

Aggref * oj_make_aggref ( Oid aggfnoid,
Oid aggtype,
Oid argtype,
Expr * arg )
static

Build an Aggref for a single-argument aggregate.

Definition at line 8008 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_count_star()

Aggref * oj_make_count_star ( void )
static

A fresh count(*) Aggref (returns int8).

Definition at line 9016 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_subquery_rte()

RangeTblEntry * oj_make_subquery_rte ( Query * sub)
static

Wrap a constructed Query as an RTE_SUBQUERY, building its eref->colnames from the (non-junk) target list.

Definition at line 7247 of file provsql.c.

Here is the caller graph for this function:

◆ oj_neutralize_orphan_arm()

void oj_neutralize_orphan_arm ( RangeTblEntry * rel)
static

Neutralise an outer-join arm RTE left orphaned after the lowering so get_provenance_attributes does not re-pick it up as a provenance source: a base relation has its provsql column renamed; a subquery (which would still be processed) is turned into an inert RTE_RESULT.

Definition at line 7298 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_outer_remap()

Node * oj_outer_remap ( Node * node,
void * cx )
static

Definition at line 7724 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_param_repl_mut()

Node * oj_param_repl_mut ( Node * node,
void * cx )
static

Replace every PARAM_SUBLINK with paramid by replacement.

Definition at line 8404 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_refs_join_index()

bool oj_refs_join_index ( Query * q,
Index join_idx )
static

True if any outer Var references the join RTE directly (USING / whole-row / alias.col references the conservative remap cannot resolve through joinaliasvars yet).

Definition at line 7703 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_renum_mut()

Node * oj_renum_mut ( Node * node,
void * cx )
static

Definition at line 7329 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_rtables_coalescible()

bool oj_rtables_coalescible ( List * rta,
List * rtb )
static

Can two scalar-subquery bodies share a single decorrelating LEFT JOIN?

True when both are plain value bodies (no aggregate / DISTINCT / ORDER BY / LIMIT) over the same single relation Q with the same correlation WHERE, differing only in the one selected value. Then a single "R ⟕ Q ON corr" group serves both: one count(Q.key) <= 1 gate, a choose() per sublink. Used to decorrelate several correlated target-list sublinks that share a (Q, corr) – e.g. "(SELECT Q.x WHERE Q.k=R.k), (SELECT Q.y WHERE Q.k=R.k)" – in one pass.

equal() on two single-RTE rtables, ignoring per-RTE ACL fields.

Before PostgreSQL 16 the permission bookkeeping (requiredPerms, selectedCols…) lived inside RangeTblEntry, so two sublink bodies over the same Q differing only in the selected value column would spuriously compare unequal (their selectedCols differ). PG16 moved those fields out into Query.rteperminfos and a plain equal() suffices.

Definition at line 9482 of file provsql.c.

Here is the caller graph for this function:

◆ oj_rte_has_provsql()

bool oj_rte_has_provsql ( const constants_t * constants,
RangeTblEntry * rel )
static

True if rel contributes provenance: a base relation with a provsql UUID column, or a subquery over tracked relations.

Definition at line 7213 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_sl_replace_mut()

Node * oj_sl_replace_mut ( Node * node,
void * cx )
static

Definition at line 7989 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_sub_bodies_coalescible()

bool oj_sub_bodies_coalescible ( Query * a,
Query * b )
static

Definition at line 9500 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_sublink_scan_walker()

bool oj_sublink_scan_walker ( Node * node,
void * cx )
static

Definition at line 7964 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_uncorrelated_body_over_tracked()

bool oj_uncorrelated_body_over_tracked ( const constants_t * constants,
Query * sub )
static

Is sub an uncorrelated clean SELECT over tracked base relations (a comma-join is fine)?

The targetList is not inspected (callers replace it).

Definition at line 8989 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_wrap_body_from()

bool oj_wrap_body_from ( const constants_t * constants,
Query * sub )
static

Collapse a multi-table scalar-subquery body FROM into one derived cross-product subquery D, so the decorrelation can treat the body as "SELECT val FROM D WHERE W" with D a single tracked subquery.

Mirror of oj_wrap_outer_from, but for the SubLink body: every body relation must be a tracked base relation and the FROM a comma-join. D exposes every base user column (oj_collect_cols); the body's own (level-0) references are retargeted to D, while the correlated level-1 references to the outer query are left untouched. The body WHERE W (correlation + inter-table join) stays in place: it becomes the "R LEFT JOIN D" ON clause, and get_provenance_attributes later processes D recursively, giving it the Q1 ⊗ … ⊗ Qn provenance.

Definition at line 8813 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_wrap_outer_from()

bool oj_wrap_outer_from ( const constants_t * constants,
Query * q,
SubLink * sl,
bool in_where )
static

Wrap a non-single-relation outer FROM into a derived subquery R' so a scalar subquery can be decorrelated onto it.

Builds R' = the outer FROM (all its base relations + join RTEs) with the non-subquery WHERE conjuncts, exposing every base-relation user column. The outer query is rewritten to "FROM R'" with all references (the target list, the SubLink's correlation at level 1, and – for a WHERE SubLink – the conjunct that will move to HAVING) retargeted to R''s columns. The FROM must consist only of base relations and join RTEs (no nested subqueries / VALUES / functions); returns false otherwise, leaving q untouched.

Definition at line 8153 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_wrap_remap_mut()

Node * oj_wrap_remap_mut ( Node * node,
void * cx )
static

Definition at line 8116 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ oj_zero_satisfies()

bool oj_zero_satisfies ( Oid opno,
Const * c )
static

Does 0 satisfy the int8 comparison "0 <opno> c"?

Detects count(*) predicates that hold on the empty group (so the HAVING-gate would drop them and the antijoin construction is needed instead).

Definition at line 9217 of file provsql.c.

Here is the caller graph for this function:

◆ peel_agg_casts()

Node * peel_agg_casts ( Node * n)
static

Peel implicit/explicit cast FuncExprs and RelabelTypes that wrap a single argument, returning the underlying expression.

Used to see through the coercions the parser inserts around an aggregate (e.g. the int8->numeric cast in count(*)/2.0) so the underlying agg_token / provenance_aggregate can be recognised.

Definition at line 5436 of file provsql.c.

Here is the caller graph for this function:

◆ predicate_subselect_decorrelatable()

bool predicate_subselect_decorrelatable ( const constants_t * constants,
Query * sub,
bool corr_supplied )
static

Is sub a subselect that the predicate-sublink rewrite can turn into a correlated "SELECT count(*) FROM Q WHERE corr"?

Requires a body FROM over tracked base relations – a single relation Q, or an all-tracked comma-join that oj_wrap_body_from collapses downstream into one derived cross-product subquery – and a (correlated) WHERE, with none of the shapes decorrelate_scalar_sublinks rejects downstream (aggregates, grouping, set ops, LIMIT, nested sublinks, CTEs). The targetList is replaced wholesale by count(*), so its width is irrelevant here. corr_supplied is set for IN / NOT IN, whose correlation comes from the testexpr and is ANDed into the (possibly empty) subselect WHERE by the caller.

Definition at line 8301 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ predicate_to_condition_gate()

FuncExpr * predicate_to_condition_gate ( Expr * expr,
const constants_t * constants,
bool negated )
static

Convert a Boolean predicate into a provenance condition gate.

Carrier-independent counterpart of rv_Expr_to_provenance, used by the "X | (predicate)" rewrite: the predicate is a Boolean combination (AND / OR / NOT) of comparisons. A probabilistic comparison – a random_variable comparison ("X > 3", lowered by rv_OpExpr_to_provenance_cmp) or an agg_token comparison ("SUM(x) > 5", lowered by having_OpExpr_to_provenance_cmp) – becomes its gate. A purely-regular SUB-expression (no probabilistic comparison, e.g. "region = 'north'") becomes the deterministic indicator regular_indicator(cond) (χ: gate_one when it holds, gate_zero otherwise), so a MIXED predicate is supported per the HAVING-provenance semantics. Returns the uuid gate representing "the predicate holds": AND maps to provenance_times, OR to provenance_plus, NOT flips negated (De Morgan), mirroring rv_BoolExpr_to_provenance.

Definition at line 3645 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_inert_fetches()

void process_inert_fetches ( const constants_t * constants,
Query * q )
static

Definition at line 12057 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_inert_fetches_walker()

bool process_inert_fetches_walker ( Node * node,
void * cx )
static

Definition at line 12029 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_insert_select()

void process_insert_select ( const constants_t * constants,
Query * q )
static

Propagate provenance through INSERT ... SELECT.

If the source SELECT involves provenance-tracked tables and the target table has a provsql column, rewrites the source SELECT to carry provenance and maps its provsql output to the target's provsql column, replacing the default uuid_generate_v4().

If the target has no provsql column, emits a warning instead.

Definition at line 12672 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_query()

Query * process_query ( const constants_t * constants,
Query * q,
bool ** removed,
bool wrap_root,
bool top_level,
bool in_boolean_rewrite,
const InvFreeMarkerCtx * inv_ctx )
static

Rewrite a single SELECT query to carry provenance.

This is the recursive entry point for the provenance rewriter. It is called from provsql_planner for top-level queries and re-entered from get_provenance_attributes for subqueries in FROM.

High-level steps:

  1. Strip any provsql column propagated into this query's target list.
  2. Detect and rewrite structural forms requiring pre-processing: non-ALL set operations (wrap in outer GROUP BY), AGG DISTINCT (push into a subquery), DISTINCT (convert to GROUP BY).
  3. Collect provenance attributes via get_provenance_attributes.
  4. Build a column-numbering map for where-provenance (build_column_map).
  5. Handle aggregates, migrate WHERE-on-aggregate to HAVING, and set ops.
  6. Build and splice the combined provenance expression.
Parameters
constantsExtension OID cache.
qQuery to rewrite (modified in place).
removedOut-param: boolean array indicating which original target list entries were provenance columns and were removed. May be NULL if the caller does not need this info.
wrap_rootIf true, mark this query's provenance expression as a safe-query root that must be wrapped in provsql.assume_boolean before splicing.
top_levelTrue for the outermost query the user evaluates; gates the inversion-free analysis (run only at the top).
in_boolean_rewriteTrue once a safe-query (boolean) rewrite has fired above; propagated through every recursion (including into subqueries, where wrap_root is otherwise lost) so the joint-width recogniser defers to the safe rewrite everywhere in its subtree.
inv_ctxInversion-free marker context supplied by a parent that flattened this query as a subquery, or NULL; when set, this query applies the supplied per-input markers instead of running its own analysis or read-once rewrite.
Returns
The (possibly restructured) rewritten query, or NULL if the query has no FROM clause and can be skipped.

Definition at line 12105 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_set_operation_union()

void process_set_operation_union ( const constants_t * constants,
SetOperationStmt * stmt,
Query * q )
static

Recursively annotate a UNION tree with the provenance UUID type.

Walks the SetOperationStmt tree of a UNION and appends the UUID type to colTypes / colTypmods / colCollations on every node, and sets all = true so that PostgreSQL does not deduplicate the combined stream. The non-ALL deduplication has already been moved to an outer GROUP BY by rewrite_non_all_into_external_group_by before this is called.

Parameters
constantsExtension OID cache.
stmtRoot (or subtree) of the UNION SetOperationStmt.
qOuter query (to look up subquery RTEs for agg_token type updates).

Definition at line 10136 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provenance_function_in_group_by()

bool provenance_function_in_group_by ( const constants_t * constants,
Query * q )
static

Check whether a provenance() call appears in the GROUP BY list.

When the user writes GROUP BY provenance(), ProvSQL must not add its own group-by wrapper (the query is already grouping on the token).

Parameters
constantsExtension OID cache.
qQuery to inspect.
Returns
True if any GROUP BY key contains a provenance() call.

Definition at line 6136 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provenance_function_walker()

bool provenance_function_walker ( Node * node,
void * data )
static

Tree walker that returns true if any provenance() call is found.

Used to detect whether a query explicitly calls provenance(), which triggers the substitution in replace_provenance_function_by_expression.

Parameters
nodeCurrent expression tree node.
dataPointer to constants_t (cast from void*).
Returns
true if a provenance() call is found anywhere in node.

Definition at line 6111 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provenance_in_sublink_walker()

bool provenance_in_sublink_walker ( Node * node,
void * data )
static

Walker: true if a SubLink subselect calls provenance().

A SubLink subselect (scalar / IN / EXISTS) is planned standalone, so it never goes through this hook – a provenance() call inside one is never rewritten and falls through to its runtime stub (NULL or a misleading error). ProvSQL does not propagate provenance through a SubLink, so we detect the provenance() use up front and raise a clear error instead.

Only the explicit provenance() call is flagged, not a mere read of a tracked relation's columns: (SELECT array_agg(provsql) FROM t) and other plain column reads inside a SubLink are legitimate and must keep working. Tracked relations reached through the FROM clause (RTE_SUBQUERY) are fully supported and never reach this walker's SubLink arm.

Definition at line 6705 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provenance_mutator()

Node * provenance_mutator ( Node * node,
void * ctx )
static

Tree-mutator that replaces provenance() calls with the actual provenance expression.

Parameters
nodeCurrent expression tree node.
ctxPointer to a provenance_mutator_context (provenance expression and constants).
Returns
Possibly modified node.

Definition at line 5816 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_ctas_kind_label()

const char * provsql_ctas_kind_label ( provsql_table_kind k)
static

Map provsql_table_kind to its textual label (set_table_info accepts text).

Definition at line 13213 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_executor_end()

void provsql_executor_end ( QueryDesc * queryDesc)
static

Definition at line 13007 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_executor_start()

void provsql_executor_start ( QueryDesc * queryDesc,
int eflags )
static

Definition at line 12990 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_planner()

PlannedStmt * provsql_planner ( Query * q,
int cursorOptions,
ParamListInfo boundParams )
static

PostgreSQL planner hook – entry point for provenance rewriting.

Replaces (or chains after) the standard planner. For every CMD_SELECT that involves at least one provenance-bearing relation or an explicit provenance() call, rewrites the query via process_query before handing the result to the standard planner. Non-SELECT commands and queries without provenance are passed through unchanged.

Parameters
qThe query to plan.
cursorOptionsCursor options bitmask.
boundParamsPre-bound parameter values.
Returns
The planned statement.

Definition at line 12863 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_ProcessUtility()

void provsql_ProcessUtility ( PlannedStmt * pstmt,
const char * queryString,
ProcessUtilityContext context,
ParamListInfo params,
QueryEnvironment * queryEnv,
DestReceiver * dest,
char * completionTag )
static

Definition at line 13413 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_ProcessUtility_apply()

void provsql_ProcessUtility_apply ( Node * parsetree,
ProvSQLCtasCapture * cap )
static

Apply cap to the freshly-created relation stmt->into->rel.

For BID sources: walks the inner query's target list to align each source block-key column to its output resno. If any block-key column is missing from the projection (the CTAS dropped it), the new relation cannot honour the BID invariant under that column – the hook demotes to TID rather than asserting a now-stale block key.

Installs provenance_guard via SPI so subsequent INSERT / UPDATE OF provsql on the new relation flip its kind to OPAQUE through the standard guard path.

Definition at line 13240 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_ProcessUtility_capture()

void provsql_ProcessUtility_capture ( Node * parsetree,
ProvSQLCtasCapture * cap )
static

Decide whether parsetree is a CTAS that should trigger the ancestry hook, and if so populate cap with the inner classification, the (single) source's block-key columns, and the transitive ancestor union.

Fires only when the inner SELECT's target list projects a base- level Var (possibly through RelabelType wrappers) that resolves to the provsql column of an RTE_RELATION whose metadata is non-OPAQUE. Anything else (no provsql in the projection, classifier says OPAQUE, the projected source is itself OPAQUE) leaves cap->fire false and the post-pass becomes a no-op.

Definition at line 13097 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ provsql_provenance_assign_hook()

void provsql_provenance_assign_hook ( int newval,
void * extra )
static

Assign hook of provsql.provenance: refresh the derived per-class flags.

Definition at line 130 of file provsql.c.

Here is the caller graph for this function:

◆ push_arith_into_agg_mutator()

Node * push_arith_into_agg_mutator ( Node * node,
void * ctx )
static

Tree-mutator applying try_push_into_aggref bottom-up.

Definition at line 5664 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_defines_handmade_provsql()

bool query_defines_handmade_provsql ( Node * node,
void * cx )
static

Walker: true if any Query in the tree defines a provsql column by hand.

A non-junk target entry resnamed provsql whose expression is not a legitimate uuid-typed Var (the passthrough of a tracked relation's provsql column, which remove_provenance_attributes_select strips) is a hand-made provenance column – e.g. "provenance() AS provsql" or "expr AS provsql". It collides with the provenance column ProvSQL adds itself: the output column count desyncs and a later Var mis-binds to a non-uuid column, crashing get_gate_type when it dereferences the value as a pointer.

Run once on the user's ORIGINAL query in the planner hook, before any rewriting, so the intermediate queries ProvSQL builds (which legitimately carry a provsql column) are never visited.

Definition at line 12816 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_has_inert_fetch()

bool query_has_inert_fetch ( const constants_t * constants,
Query * q )
static

Does q's own target list / jointree / HAVING contain an inert provenance()-fetch SubLink?

Such a query must be rewritten so the early inert pass resolves the fetch, even with an otherwise-untracked outer.

Definition at line 6325 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_has_tracked_sublink()

bool query_has_tracked_sublink ( const constants_t * constants,
Query * q )
static

Does any SubLink in q's own clauses have a subselect that (transitively) involves a provenance-tracked relation?

Distinguishes the "Subqueries not supported" cases (a sublink over a tracked Q, which needs the rewrite passes) from a harmless one whose body touches no tracked relation – a deterministic filter/value (untracked data is certain, so the same in every possible world) that Postgres can evaluate directly, leaving the row's provenance unchanged. Only q's own expressions are inspected, not its range table (the outer relation is tracked, and FROM subqueries get their own process_query pass).

Definition at line 6543 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reduce_varattno_by_offset()

void reduce_varattno_by_offset ( List * targetList,
Index varno,
int * offset )
static

Adjust Var attribute numbers in targetList after columns are removed.

When provenance columns are stripped from a subquery's target list, the remaining columns shift left. This function applies a pre-computed offset array (one entry per original column) to correct all Var nodes that reference range-table entry varno.

Parameters
targetListTarget list of the outer query to patch.
varnoRange-table entry whose attribute numbers need fixing.
offsetCumulative shift per original attribute (negative or zero).

Definition at line 249 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reduce_varattno_mutator()

Node * reduce_varattno_mutator ( Node * node,
void * ctx )
static

Tree-mutator callback that adjusts Var attribute numbers.

Parameters
nodeCurrent expression tree node.
ctxPointer to a reduce_varattno_mutator_context.
Returns
Possibly modified node.

Definition at line 221 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_provenance_attribute_groupref()

void remove_provenance_attribute_groupref ( Query * q,
const Bitmapset * removed_sortgrouprefs )
static

Remove sort/group references that belonged to removed provenance columns.

After remove_provenance_attributes_select strips provenance entries from the target list, any GROUP BY, ORDER BY, or DISTINCT clause that referenced them by tleSortGroupRef must be cleaned up.

Parameters
qQuery to modify in place.
removed_sortgrouprefsBitmapset of ressortgroupref values to remove.

Definition at line 5961 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_provenance_attribute_setoperations()

void remove_provenance_attribute_setoperations ( Query * q,
bool * removed )
static

Strip the provenance column's type info from a set-operation node.

When a provenance column is removed from a UNION/EXCEPT query's target list, the matching entries in the SetOperationStmt's colTypes, colTypmods, and colCollations lists must also be removed.

Parameters
qQuery containing setOperations.
removedBoolean array (from remove_provenance_attributes_select) indicating which columns were removed.

Definition at line 5998 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_provenance_attributes_select()

Bitmapset * remove_provenance_attributes_select ( const constants_t * constants,
Query * q,
bool ** removed )
static

Strip provenance UUID columns from q's SELECT list.

Scans the target list and removes every Var entry whose column name is provsql and whose type is UUID. The remaining entries have their resno values decremented to fill the gaps.

Parameters
constantsExtension OID cache.
qQuery to modify in place.
removedOut-param: allocated boolean array (length = original target list length) where true means the corresponding entry was removed. The caller must pfree this array when done.
Returns
Bitmapset of ressortgroupref values whose entries were removed (so the caller can clean up GROUP BY / ORDER BY).

Definition at line 2178 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_provsql_from_select()

void remove_provsql_from_select ( Query * q)
static

Remove the auto-added provsql output column from a rewritten query.

The inverse of add_to_select: drops the TargetEntry named PROVSQL_COLUMN_NAME and decrements the resno of every later entry, so the column numbering stays contiguous. Used when a query was rewritten for its own provenance semantics (HAVING lifting, provenance() resolution) but the caller cannot store the provenance – e.g. an INSERT ... SELECT whose target table has no provsql column.

Definition at line 6737 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ replace_aggregations_by_provenance_aggregate()

void replace_aggregations_by_provenance_aggregate ( const constants_t * constants,
Query * q,
List * prov_atts,
semiring_operation op )
static

Replace every Aggref in q with a provenance-aware aggregate.

Walks the query tree and substitutes each Aggref node with the result of make_aggregation_expression, which wraps the original aggregate in the semimodule machinery (provenance_semimod + array_agg + provenance_aggregate).

Parameters
constantsExtension OID cache.
qQuery to mutate in place.
prov_attsList of provenance Var nodes.
opSemiring operation for combining tokens across rows.

Definition at line 5690 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ replace_having_distinct_mutator()

Node * replace_having_distinct_mutator ( Node * node,
void * ctx )
static

Mutator that replaces each AGG(DISTINCT) Aggref in a HAVING clause with Var(next_rtindex++, 1) – the deduped count column of its outer subquery (built in the same order by rewrite_agg_distinct).

The Var is typed as the aggregate's result so the surrounding comparison is intercepted by the HAVING provenance path exactly as a non-DISTINCT count would be.

Definition at line 4986 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ replace_provenance_function_by_expression()

void replace_provenance_function_by_expression ( const constants_t * constants,
Query * q,
Expr * provsql )
static

Replace every explicit provenance() call in q with provsql.

Users can write provenance() in the target list or WHERE to refer to the provenance token of the current tuple. This mutator substitutes those calls with the actual computed provenance expression.

Parameters
constantsExtension OID cache.
qQuery to mutate in place.
provsqlProvenance expression to substitute.

Definition at line 5871 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retype_agg_var_walker()

bool retype_agg_var_walker ( Node * node,
retype_agg_var_ctx * ctx )
static

Walker that retypes agg_token Vars to text and rewrites the equality OpExpr to text = text with the non-agg side cast via I/O.

Only affects Vars with varlevelsup == 0 matching (rteid, join_attno). Sibling-query subqueries are left untouched via QTW_IGNORE_RT_SUBQUERIES at the top-level call.

Definition at line 10888 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_agg_distinct()

Query * rewrite_agg_distinct ( Query * q,
const constants_t * constants )
static

Rewrite every AGG(DISTINCT key) in q using independent subqueries.

For a single DISTINCT aggregate, produces a subquery:

SELECT AGG(key), gb... FROM (SELECT key, gb... FROM t GROUP BY key, gb...) GROUP BY gb...

For multiple DISTINCT aggregates with different keys, produces an JOIN of one such subquery per aggregate, joined on the GROUP BY columns. Non-DISTINCT aggregates are left untouched.

AGG(DISTINCT) aggregates appearing in the HAVING clause are handled the same way (one deduped outer per aggregate) and the HAVING Aggref is replaced by a Var to its outer's count column, so the comparison's provenance is built over the per-distinct-value rows rather than the raw tuples.

Parameters
qQuery to inspect and possibly rewrite.
constantsExtension OID cache.
Returns
Rewritten query, or NULL if no AGG(DISTINCT) was found.

Definition at line 5028 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_array_sublinks()

bool rewrite_array_sublinks ( const constants_t * constants,
Query * q )
static

Rewrite a top-level ARRAY(SELECT Q.col FROM Q WHERE corr) target-list entry into the aggregate body (SELECT array_agg(Q.col) FROM Q WHERE corr).

A pre-pass for decorrelate_scalar_sublinks: an ARRAY_SUBLINK collects the correlated rows into an array, which is exactly array_agg over the group, so mutating it into an EXPR_SUBLINK aggregate body lets the aggregate arm lower it to array_agg(Q.col) over the "R ⟕ Q" group – no count gate, since an array may have zero, one, or many elements. Subselects that are not decorrelatable (untracked / multi-relation / uncorrelated) are left untouched.

Definition at line 8689 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_cond_predicate_mutator()

Node * rewrite_cond_predicate_mutator ( Node * node,
void * data )
static

Mutator: rewrite "X | (predicate)" into the carrier's cond.

The "|" on "(carrier, boolean)" -- and the prefix "| (boolean)" – parses to an OpExpr over a conditioning placeholder, whose Boolean operand is a combination of probabilistic comparisons. This mutator builds the condition gate from that operand (predicate_to_condition_gate) and replaces the node with "cond(X, gate)" for the carrier (or given(gate) for the prefix whole-tuple form), so the natural "X | (X > 3)" / "SUM(x) | (SUM(x) > 5)" / prefix "| (sensor > k)" syntax resolves to the existing conditioning surface. The left operand is recursively mutated so nested forms ("(X | p1) | p2") compose.

Definition at line 3762 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_cond_predicates()

void rewrite_cond_predicates ( const constants_t * constants,
Query * q )
static

Rewrite every "X | (predicate)" in q's own clauses.

Runs early in process_query (before the FROM-less early return, the given()-marker strip and the probabilistic-qual migration), over the target list, WHERE and HAVING. No-op on a schema predating the placeholders.

Definition at line 3814 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_join_agg_token()

Query * rewrite_join_agg_token ( Query * q,
const constants_t * constants,
Index rteid,
AttrNumber join_attno )
static

Replace the source relation of an agg_token JOIN with an explode-style subquery.

Given a JOIN qual of the form rteid.join_attno = other where rteid.join_attno is of type agg_token, replaces the RTE at rteid in place with a subquery:

SELECT t.col_1, ..., t.col_{join_attno-1},
get_extra(get_children(sm)[2]) AS <agg_col>,
...,
provenance_times(get_children(sm)[1], t.provsql) AS provsql
FROM <t>, LATERAL unnest(get_children(t.<agg_col>)) AS sm

The subquery preserves the original column order, so outer Vars still address the same attnos. The outer query is then walked to retype Vars at (rteid, join_attno) from agg_token to text and rewrite the equality OpExpr to text = text (casting the other side via I/O).

The copy of the source RTE inside the subquery has its provsql column renamed so the recursive process_query pass does not re-detect it as a provenance source – the combined provenance is already captured by the subquery's exposed provsql target entry.

Parameters
qQuery to rewrite (modified in place).
constantsExtension OID cache.
rteid1-based varno of the RTE owning the agg_token column.
join_attno1-based attno of the agg_token column in that RTE.
Returns
The modified query.

Definition at line 11015 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_non_all_into_external_group_by()

Query * rewrite_non_all_into_external_group_by ( Query * q)
static

Wrap a non-ALL set operation in an outer GROUP BY query.

UNION / EXCEPT (without ALL) would deduplicate tuples before ProvSQL can attach provenance tokens. To avoid this, the set operation is converted to UNION ALL / EXCEPT ALL and a new outer query is built that groups the results by all non-provenance columns, collecting tokens into an array for the provenance_plus evaluation.

After this rewrite the recursive call to process_query handles the now-ALL inner set operation normally.

Parameters
qQuery whose setOperations is non-ALL (modified to ALL in place).
Returns
New outer query that wraps q as a subquery RTE.

Definition at line 6039 of file provsql.c.

Here is the caller graph for this function:

◆ rewrite_predicate_sublinks()

bool rewrite_predicate_sublinks ( const constants_t * constants,
Query * q )
static

Rewrite top-level EXISTS / IN WHERE conjuncts (optionally negated) over a single tracked relation into correlated count(*) comparisons.

A pre-pass for decorrelate_scalar_sublinks: each qualifying conjunct (a bare EXISTS / IN sublink, or one wrapped in a single NOT – i.e. NOT EXISTS / NOT IN) is replaced by the build_count_predicate form, after which the scalar-subquery decorrelation lowers the count() comparison to the "R ⟕ Q" semijoin / antijoin. Conjuncts whose subselect is not decorrelatable (untracked / uncorrelated / non-comma-join) are left untouched, so they hit the usual unsupported-subquery error.

Definition at line 8618 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_uncorrelated_antijoin()

bool rewrite_uncorrelated_antijoin ( const constants_t * constants,
Query * q )
static

Rewrite an uncorrelated WHERE predicate that is satisfied by the empty group – NOT EXISTS, or "(SELECT count(*) FROM Q) <op> const" with "0 <op> const" true (e.g.

"< k", "<= k", "= 0") – into the EXCEPT-ALL antijoin.

Such a predicate is "NOT P" for a P that is FALSE on the empty group (EXISTS, count(*) >= k…), so it is the m-semiring antijoin "R ⊗ (1 ⊖ ⟦P⟧)". We materialise ⟦P⟧ as the one-row HAVING-gated subquery D = "SELECT 1 FROM Q [WHERE w] HAVING count(*) <negated op> const" (count(*) always yields a row, so ⟦P⟧ is correctly captured even when the group is empty), then take the difference "R EXCEPT ALL π_R(R × D)" via oj_build_diff – ProvSQL's NOT-IN EXCEPT-ALL, giving each kept tuple "R(r) ⊖ (R(r) ⊗ ⟦P⟧) = R(r) ⊗ (1 ⊖ ⟦P⟧)", multiplicity preserved and correct in every semiring.

Runs before rewrite_predicate_sublinks / move_uncorrelated_where_predicates: those would instead push the raw predicate into a HAVING-gate, whose empty group is gate_zero – dropping exactly the world this predicate selects (a silent under-count: count(*)=0 → p=0, count(*)<2P(=1) not P(≤1)).

Definition at line 9243 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_BoolExpr_to_provenance()

FuncExpr * rv_BoolExpr_to_provenance ( BoolExpr * be,
const constants_t * constants,
bool negated )
static

Convert a Boolean combination of RV comparisons into a provenance_times / provenance_plus expression.

Same De Morgan handling as having_BoolExpr_to_provenance: under negation, AND ↔ OR (which means PROVENANCE_TIMES ↔ PROVENANCE_PLUS). NOT flips negated and recurses.

Definition at line 3536 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_cmp_index()

int rv_cmp_index ( const constants_t * constants,
Oid funcoid )
static

Test whether funcoid is one of the random_variable_* comparison procedures, and if so return its ComparisonOperator index.

Parameters
constantsExtension OID cache.
funcoidProcedure OID to test (typically OpExpr->opfuncid).
Returns
Index in [0..6) on match, -1 otherwise. Match indices line up with ComparisonOperator (EQ=0, NE=1, LE=2, LT=3, GE=4, GT=5).

Definition at line 3442 of file provsql.c.

Here is the caller graph for this function:

◆ rv_Expr_to_provenance()

FuncExpr * rv_Expr_to_provenance ( Expr * expr,
const constants_t * constants,
bool negated )
static

Dispatch a WHERE sub-expression to the appropriate RV converter.

Entry point for the mutual recursion between rv_BoolExpr_to_provenance and rv_OpExpr_to_provenance_cmp.

Definition at line 3586 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_OpExpr_to_provenance_cmp()

FuncExpr * rv_OpExpr_to_provenance_cmp ( OpExpr * opExpr,
const constants_t * constants,
bool negated )
static

Convert a single RV-comparison OpExpr into a provenance_cmp() FuncExpr returning UUID.

If negated is true the operator OID is replaced by its negator (so NOT (a > b) becomes a ≤ b at the provenance level), exactly as having_OpExpr_to_provenance_cmp does.

Parameters
opExprThe comparison expression from the WHERE clause. Must satisfy rv_cmp_index(opExpr->opfuncid) ≥ 0; callers are responsible for the type check.
constantsExtension OID cache.
negatedWhether the expression appears under a NOT.

Definition at line 3497 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_ancestors()

Datum set_ancestors ( PG_FUNCTION_ARGS )
extern

PostgreSQL-callable wrapper for setTableAncestry() over the IPC pipe.

Records the base-relation ancestor set of a tracked relation. relid is the pg_class OID of the relation; ancestors is an oid[] (possibly empty) listing the base add_provenance / repair_key relations this one's atoms ultimately come from. The worker preserves the relation's existing kind / block_key half on update.

Silently no-op on the worker side when relid has no kind record yet – the safe-query rewriter only consults ancestry for tracked relations, so callers should run add_provenance / repair_key / set_table_info first.

Definition at line 847 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_table_info()

Datum set_table_info ( PG_FUNCTION_ARGS )
extern

Forward declaration of the C SQL entry points.

Forward declaration of the C SQL entry points.

Stores per-relation provenance metadata used by the safe-query optimisation. relid is the pg_class OID of the relation; kind is one of the textual labels 'tid' / 'bid' / 'opaque' (see provsql_table_kind in MMappedTableInfo.h); block_key is an int2 array (possibly empty) listing the block-key column numbers when kind is 'bid'.

Definition at line 635 of file provsql_mmap.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ strip_given_markers()

List * strip_given_markers ( const constants_t * constants,
Query * q )
static

Strip given(evidence) whole-tuple conditioning markers from the visible projection, returning the captured evidence expressions.

Walks q's target list for visible (non-resjunk) entries whose expression is a provsql.given(uuid) FuncExpr – the consumed marker emitted by the prefix | operator / given() call. Each match is removed from the projection (its resno renumbered like remove_provenance_attributes_ select), and its single argument (the per-row evidence token) is collected into the returned list, in target-list order. The caller wraps the query's output provenance in cond(row_provenance, evidence) for each captured expression, so multiple markers accumulate as a conjunction of evidence (cond folds "(X|A)|B = X|(A∧B)").

Returns NIL when the query carries no marker (the common case, no cost beyond the walk). q's target list is modified in place.

Definition at line 2253 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_classify_walker()

bool sublink_classify_walker ( Node * node,
void * cx )
static

Walker classifying each tracked SubLink of a query as either a still-unsupported direct form or an arithmetic-nested one.

Stops descending at a tracked sublink (its subselect is Postgres' business once we decide to pass it through); keeps descending through untracked sublinks so a tracked one nested deeper is still found.

Definition at line 6614 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_is_inert()

bool sublink_is_inert ( SubLink * sl)
static

Does sl wrap a recorded inert provenance()-fetch subselect?

Such a SubLink is an untracked scalar value: the decorrelation / move-to-FROM passes must leave it alone (moving or aggregating it would couple its relation into the outer lineage and wrap the token in an aggregate gate).

Definition at line 6267 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_over_tracked_walker()

bool sublink_over_tracked_walker ( Node * node,
void * cx )
static

Walker: set found if a SubLink whose subselect (transitively) involves a provenance-tracked relation is reached.

Definition at line 6512 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ subselect_is_pure_provenance_fetch()

bool subselect_is_pure_provenance_fetch ( const constants_t * constants,
Query * sub )
static

Whether sub's sole non-junk output is a bare provenance() call.

Checked before resolution (the target is still the raw provenance() FuncExpr). The supported shape is deliberately narrow – a plain scan projecting only provenance(): exactly one visible target entry, and it is provenance(), with no aggregation / grouping / HAVING / set-op / DISTINCT / window (those carry probabilistic-provenance semantics an inert, physically-evaluated fetch would not honour, so they stay on the ordinary path). A subselect bringing any other column likewise stays correlated.

Definition at line 6284 of file provsql.c.

Here is the caller graph for this function:

◆ transform_distinct_into_group_by()

void transform_distinct_into_group_by ( Query * q)
static

Convert a SELECT DISTINCT into an equivalent GROUP BY.

ProvSQL cannot handle DISTINCT directly (it would collapse provenance tokens that should remain separate). This function moves every entry from q->distinctClause into q->groupClause (skipping any that are already there) and clears q->distinctClause.

Parameters
qQuery to modify in place.

Definition at line 5895 of file provsql.c.

Here is the caller graph for this function:

◆ transform_except_into_join()

bool transform_except_into_join ( const constants_t * constants,
Query * q )
static

Rewrite an EXCEPT query into a LEFT JOIN with monus provenance.

EXCEPT cannot be handled directly because it deduplicates. This function transforms:

SELECT … FROM A EXCEPT SELECT … FROM B

into a LEFT JOIN of A and B on equality of all non-provenance columns, clears setOperations, and leaves the monus token combination to make_provenance_expression (which will see SR_MONUS).

Only simple (non-chained) EXCEPT is supported; chained EXCEPT raises an error.

Parameters
constantsExtension OID cache.
qQuery to rewrite in place.
Returns
Always true (errors out on unsupported cases).

Definition at line 6916 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_push_into_aggref()

Node * try_push_into_aggref ( OpExpr * op,
const constants_t * constants )
static

Push distributive constant arithmetic into an aggregate's argument.

Rewrites f(x) <op> c to f(x <op'> c) when f distributes over the arithmetic, so the result is a clean aggregate over transformed per-row values rather than a gate_arith wrapping the aggregate. Run before the aggregate is lowered, so the provenance machinery then builds an ordinary gate_agg. Only the cases that distribute without flipping the aggregate and without integer-division rounding are handled (the rest fall through to the gate_arith path):

  • sum, avg: *c (either side), unary -; avg also +c / -c.
  • min, max: +c (either side), -c (aggregate on the left). The transformed argument must keep the original argument's type (so the aggregate's function/type stay valid); otherwise no push happens. Returns the rewritten Aggref, or NULL when op is not such a case.

Definition at line 5578 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_swap_agg_arith()

Node * try_swap_agg_arith ( OpExpr * op,
const constants_t * constants )
static

Rebuild an arithmetic operator over an aggregate so the result stays an agg_token (provenance preserved).

When an arithmetic operator (+ - * /, or prefix unary -) has an agg_token operand (after peeling the parser's coercions), the default rewriting would cast that agg_token to its scalar aggregate type, silently dropping provenance. Instead, we re-resolve the operator against the agg_token operand via make_op, which selects the native agg_token arithmetic operators – the arithmetic is then recorded symbolically as a gate_arith over the operand provenance, exactly like arithmetic on random_variable. Returns the rebuilt agg_token expression, or NULL if op is not arithmetic over an aggregate.

Definition at line 5468 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_agg_token_with_cast()

Node * wrap_agg_token_with_cast ( FuncExpr * prov_agg,
const constants_t * constants )
static

Wrap a provenance_aggregate FuncExpr with a cast to the original aggregate return type.

Parameters
prov_aggThe provenance_aggregate FuncExpr to wrap.
constantsExtension OID cache.
Returns
Cast FuncExpr wrapping prov_agg.

Definition at line 5313 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_in_annotate()

Expr * wrap_in_annotate ( const constants_t * constants,
Expr * expr,
const char * cert )
static

Wrap expr in a provsql.annotate(uuid, text) FuncExpr carrying cert.

Used by make_provenance_expression to attach the inversion-free tractability certificate to the per-row provenance root: the resulting annotation gate is transparent for every evaluator and carries cert in its extra (and folded into its UUID). cert is copied into a text Const.

Definition at line 11393 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_in_assume_boolean()

Expr * wrap_in_assume_boolean ( const constants_t * constants,
Expr * expr )
static

Wrap expr in a provsql.assume_boolean FuncExpr.

Used by make_provenance_expression when its caller (the safe-query rewrite path in process_query) flagged the result as needing the gate_assumed structural marker. Wrapping at expression-build time rather than at splice time means add_to_select and replace_provenance_function_by_expression both consume the already-wrapped expression, so every per-row root occurrence in the final target list – the auto-added provsql column and every substituted user-side provenance() call – carries the wrapper uniformly.

Parameters
constantsExtension OID cache.
exprProvenance expression to wrap.
Returns
A FuncExpr applying provsql.assume_boolean to expr.

Definition at line 11368 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_in_cond()

Expr * wrap_in_cond ( const constants_t * constants,
Expr * target,
Expr * evidence )
static

Wrap target in a provsql.cond(uuid, uuid) FuncExpr conditioning it on evidence.

Used by process_query when the query carries a given(...) marker: the per-row output provenance target is conditioned on the marker's evidence expression, so each output row's provenance becomes "cond(row_provenance, evidence)". evidence is the (per-row, possibly correlated) argument captured from the stripped given() term.

Definition at line 11420 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_inversion_free_markers()

void wrap_inversion_free_markers ( const constants_t * constants,
Query * q,
List * prov_atts,
const InvFreeMarker * markers,
int natoms )
static

Replace each certified atom's provenance Var in prov_atts with its per-input-marker-wrapped form (in place).

Definition at line 11531 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_mobius_or_null()

Expr * wrap_mobius_or_null ( const constants_t * constants,
Expr * mobius_call )
static

Wrap a Möbius call in mobius_or_null(...): the token if it roots a gate_mobius (a Möbius success), else NULL (a Möbius decline returns the lineage, never a gate_mobius).

Returns mobius_call unwrapped if the helper cannot be resolved (older schema).

Definition at line 4140 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_random_variable_uuid()

Expr * wrap_random_variable_uuid ( Node * operand,
const constants_t * constants )
static

Wrap an expression returning random_variable in a binary-coercible cast to uuid.

Operand of the comparison may be a Var, a constant lifted by an implicit cast, or another OpExpr (e.g. a + b). random_variable and uuid share the same byte layout, so we emit a RelabelType node – the planner sees a zero-cost type relabel, the executor never dispatches through a runtime conversion function.

Definition at line 3463 of file provsql.c.

Here is the caller graph for this function:

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Required PostgreSQL extension magic block.

Definition at line 79 of file provsql.c.

◆ prev_ExecutorEnd

ExecutorEnd_hook_type prev_ExecutorEnd = NULL
static

Definition at line 12988 of file provsql.c.

◆ prev_ExecutorStart

ExecutorStart_hook_type prev_ExecutorStart = NULL
static

Definition at line 12987 of file provsql.c.

◆ prev_planner

planner_hook_type prev_planner = NULL
static

Previous planner hook (chained).

Definition at line 141 of file provsql.c.

◆ prev_ProcessUtility

ProcessUtility_hook_type prev_ProcessUtility = NULL
static

Definition at line 13069 of file provsql.c.

◆ provsql_absorptive_provenance

bool provsql_absorptive_provenance = false

Derived flag: the session's provenance class is 'absorptive' or 'boolean' – licenses constructions sound for absorptive semirings only (cyclic recursive queries stopped at the absorptive value fixpoint, the bounded-treewidth reachability route's certified circuits, absorptive circuit simplifications; tokens tagged accordingly). Set from the provsql.provenance GUC.

Derived flag of the provsql.provenance GUC: the session's provenance class is 'absorptive' or 'boolean', licensing constructions sound for absorptive semirings only (cyclic recursion stopped at the absorptive value fixpoint, tagged tokens).

Definition at line 108 of file provsql.c.

◆ provsql_active

bool provsql_active = true
static

true while ProvSQL query rewriting is enabled

Definition at line 86 of file provsql.c.

◆ provsql_aggtoken_text_as_uuid

bool provsql_aggtoken_text_as_uuid = false

When true, agg_token::text emits the underlying provenance UUID instead of "value (*)".

Global flag controlling agg_token text output: when true, agg_token_out emits the underlying provenance UUID instead of the default "value (*)" display string.

Definition at line 91 of file provsql.c.

◆ provsql_boolean_provenance

bool provsql_boolean_provenance = false

Derived flag: the session's provenance class is 'boolean' – enables the Boolean-only machinery (safe-query read-once rewrite, Boolean circuit simplifications), whose outputs are tagged so that semiring evaluations admitting no homomorphism from Boolean functions refuse to run on them. Set from the provsql.provenance GUC.

GUC: opt-in safe-query optimisation, declared in provsql.c.

Opt-in safe-query optimisation for hierarchical conjunctive queries; see the provsql.boolean_provenance GUC.

Definition at line 107 of file provsql.c.

◆ provsql_cmp_probability_evaluation

bool provsql_cmp_probability_evaluation = true

Run closed-form / analytic probability evaluators for gate_cmps inside probability_evaluate (currently the Poisson-binomial pre-pass for HAVING-COUNT; future MIN / MAX / SUM evaluators will gate on the same GUC); controlled by the provsql.cmp_probability_evaluation GUC.

Hidden diagnostic flag for the family of closed-form / analytic probability evaluators that resolve gate_cmps inside probability_evaluate ; see the provsql.cmp_probability_evaluation GUC.

Definition at line 105 of file provsql.c.

◆ provsql_dtree_max_subproblems

int provsql_dtree_max_subproblems = 0

Debug/safety hard cap on d-tree subproblems before it bails (0 = off; the chooser auto-budgets at the next-best method's cost regardless); provsql.dtree_max_subproblems GUC.

Definition at line 97 of file provsql.c.

◆ provsql_executor_depth

int provsql_executor_depth = 0
static

Executor nesting depth.

Tracks how deep we are inside Executor invocations. Incremented in provsql_executor_start, decremented in provsql_executor_end. The classifier NOTICE only fires when this is zero, which corresponds to the user's outermost statement being planned (before any executor entry). Plans built for PL/pgSQL function bodies that the rewriter inserts – provenance_times, provenance_plus, provenance_aggregate, ... – happen during execution of the user's plan, so they see depth >= 1 and skip the NOTICE.

Definition at line 12848 of file provsql.c.

◆ provsql_fallback_compiler

char* provsql_fallback_compiler = NULL

Compiler used by BooleanCircuit::makeDD as the final fallback after interpretAsDD and tree-decomposition both fail; controlled by the provsql.fallback_compiler GUC (default "d4").

Compiler invoked as the final fallback in BooleanCircuit::makeDD when both interpretAsDD() and the in-process tree-decomposition path fail (the latter typically on treewidth blow-up).

Definition at line 93 of file provsql.c.

◆ provsql_hybrid_evaluation

bool provsql_hybrid_evaluation = true

Run the hybrid-evaluator simplifier inside probability_evaluate; controlled by the provsql.hybrid_evaluation GUC.

Run the hybrid evaluator (simplifier + per-cmp island decomposer) before dispatching a probability_evaluate query.

Definition at line 104 of file provsql.c.

◆ provsql_inert_subselects

List* provsql_inert_subselects = NIL
static

Walker (this query level only): true if an EXPR_SUBLINK whose body is a decorrelatable value subquery over a provenance-tracked base relation appears in an expression.

Lets the planner gate engage for a scalar subquery over a tracked relation even when the OUTER query has no tracked relation – decorrelate_scalar_ sublinks then handles it (wrapping the untracked outer with a certain gate_one() provenance and warning that its tuple provenance is lost). The shape conditions mirror decorrelate's subselect validation, so engagement implies the decorrelation succeeds (no engage-then-error regression); a non-decorrelatable scalar subquery still leaves the gate untouched and runs as plain SQL. Does not descend into nested Query / SubLink subselects.

Definition at line 6255 of file provsql.c.

◆ provsql_interrupted

bool provsql_interrupted = false

Global variable that becomes true if this particular backend received an interrupt signal.

Definition at line 85 of file provsql.c.

◆ provsql_inversion_free

bool provsql_inversion_free = true

Insert the inversion-free structured-d-DNNF path into the default probability chain (after independent, when a certificate is present); controlled by the provsql.inversion_free GUC.

Kill-switch for the inversion-free structured-d-DNNF probability path; see the provsql.inversion_free GUC.

Definition at line 106 of file provsql.c.

◆ provsql_joint_max_states

int provsql_joint_max_states = 65536

Per-bag DP state-count cap of the joint-width UCQ compiler (the true safety net); provsql.joint_max_states GUC.

Definition at line 99 of file provsql.c.

◆ provsql_joint_max_treewidth

int provsql_joint_max_treewidth = 10

Maximum joint treewidth the joint-width UCQ compiler attempts before declining (caller falls back to the ladder); provsql.joint_max_treewidth GUC.

Definition at line 98 of file provsql.c.

◆ provsql_joint_width

bool provsql_joint_width = true

Recognise unsafe UCQs at planner time and route their existence provenance through the joint-width compiler (on by default); the provsql.joint_width GUC is a debug-only switch to disable it.

Definition at line 100 of file provsql.c.

◆ provsql_kcmcp_server

char* provsql_kcmcp_server = NULL

Launch command for the managed KCMCP server (with a {endpoint} placeholder); controlled by the provsql.kcmcp_server GUC. Empty means no managed server is launched.

Launch command for the managed KCMCP knowledge-compiler server, set by the provsql.kcmcp_server run-time configuration parameter (PGC_SIGHUP).

Definition at line 94 of file provsql.c.

◆ provsql_last_eval_method

char* provsql_last_eval_method = NULL

Last probability evaluation method(s) used; exposed via provsql.last_eval_method.

Global variable holding the probability evaluation method(s) used by the most recent probability_evaluate call, exposed via the provsql.last_eval_method run-time configuration parameter.

Definition at line 90 of file provsql.c.

◆ provsql_mobius

bool provsql_mobius = true

Try the safe-UCQ Möbius-inversion route (a guaranteed-PTIME exact route for its class) BEFORE the joint-width compiler, which it short-circuits on success (on by default); the provsql.mobius GUC is a debug-only switch to disable it.

Definition at line 101 of file provsql.c.

◆ provsql_mobius_max_gates

int provsql_mobius_max_gates = 4000000

Data-cost cap of the Möbius route: it declines (falling through to joint-width / the ladder) once its compile has built more than this many gates, bounding the \(O(|D|^k)\) blow-up of a high-level safe query on large data; provsql.mobius_max_gates GUC.

Definition at line 102 of file provsql.c.

◆ provsql_monte_carlo_seed

int provsql_monte_carlo_seed = -1

Seed for the Monte Carlo sampler; -1 means non-deterministic (std::random_device); controlled by the provsql.monte_carlo_seed GUC.

Seed for the Monte Carlo sampler, set by the provsql.monte_carlo_seed run-time configuration parameter.

Definition at line 95 of file provsql.c.

◆ provsql_provenance_class

int provsql_provenance_class = PROVSQL_PROVENANCE_SEMIRING
static

Backing variable of the provsql.provenance GUC.

Definition at line 118 of file provsql.c.

◆ provsql_provenance_options

const struct config_enum_entry provsql_provenance_options[]
static
Initial value:
= {
{"where", PROVSQL_PROVENANCE_WHERE, false},
{"semiring", PROVSQL_PROVENANCE_SEMIRING, false},
{"absorptive", PROVSQL_PROVENANCE_ABSORPTIVE, false},
{"boolean", PROVSQL_PROVENANCE_BOOLEAN, false},
{NULL, 0, false}
}
@ PROVSQL_PROVENANCE_WHERE
Universal semiring provenance plus where-provenance gates.
Definition provsql.c:112
@ PROVSQL_PROVENANCE_BOOLEAN
Boolean-only machinery licensed (tagged); implies absorptive.
Definition provsql.c:115
@ PROVSQL_PROVENANCE_SEMIRING
Universal semiring provenance (default).
Definition provsql.c:113
@ PROVSQL_PROVENANCE_ABSORPTIVE
Absorptive-semiring constructions licensed (tagged).
Definition provsql.c:114

Option table of the provsql.provenance GUC.

Definition at line 121 of file provsql.c.

◆ provsql_rv_mc_samples

int provsql_rv_mc_samples = 10000

Default sample count for analytical-evaluator MC fallbacks; 0 disables fallback (callers raise instead); controlled by the provsql.rv_mc_samples GUC.

Default sample count for Monte Carlo fallbacks when an analytical evaluator (Expectation, future hybrid evaluator, ...) cannot decompose a sub-circuit structurally.

Definition at line 96 of file provsql.c.

◆ provsql_simplify_on_load

bool provsql_simplify_on_load = true

Run universal cmp-resolution passes when getGenericCircuit returns; controlled by the provsql.simplify_on_load GUC.

When true (default), every GenericCircuit returned by getGenericCircuit is run through the universal cmp-resolution passes (RangeCheck for now, plus any future passes that decide comparators to certain Boolean values).

Definition at line 103 of file provsql.c.

◆ provsql_tool_search_path

char* provsql_tool_search_path = NULL

Colon-separated directory list prepended to PATH when invoking external tools (d4, c2d, minic2d, dsharp, weightmc, graph-easy); controlled by the provsql.tool_search_path GUC. Superuser-only (PGC_SUSET): it dictates which directories the postgres OS user searches for executables, so a non-privileged role must not be able to point it at an attacker-controlled binary.

Colon-separated list of directories prepended to PATH when ProvSQL spawns external tools (d4, c2d, minic2d, dsharp, weightmc, graph-easy), set by the provsql.tool_search_path run-time configuration parameter.

Definition at line 92 of file provsql.c.

◆ provsql_update_provenance

bool provsql_update_provenance = false
static

true when provenance tracking for DML is enabled

Definition at line 88 of file provsql.c.

◆ provsql_verbose

int provsql_verbose = 100

Verbosity level; controlled by the provsql.verbose_level GUC.

Global variable that indicates the verbosity level set by the provsql.verbose_level run-time configuration parameter was set.

Definition at line 89 of file provsql.c.

◆ provsql_where_provenance

bool provsql_where_provenance = false

Global variable that indicates if where-provenance support has been activated through the provsql.where_provenance run-time configuration parameter.

Definition at line 87 of file provsql.c.