![]() |
ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
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"
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... | |
| struct | sublink_tracked_ctx |
Context for sublink_over_tracked_walker. More... | |
| struct | sublink_classify_ctx |
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... | |
| struct | oj_sublink_scan |
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 FlatAtomOrigin * | flat_origin1 (int slot) |
A depth-1 origin path [slot]. | |
| static FlatAtomOrigin * | flat_origin_prepend (int slot, const FlatAtomOrigin *sub) |
Prepend slot to sub's path, for an atom inlined one level up. | |
| static FlatAtomOrigin * | flatten_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 InvFreeMarkerCtx * | build_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 |
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:
provsql UUID column (get_provenance_attributes).make_provenance_expression, make_aggregation_expression).provenance() call in the query with the computed expression (add_to_select, replace_provenance_function_by_expression). Definition in file provsql.c.
Values of the provsql.provenance enum GUC, from most general to most specialised.
| 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 |
| enum 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).
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). |
|
extern |
|
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.

|
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).
| constants | Extension OID cache. |
| fromOpExpr | The equality OpExpr to inspect. |
| toExpr | Existing provenance expression to wrap. |
| columns | Per-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. |
toExpr wrapped in provenance_eq(toExpr, col1, col2), or toExpr unchanged if the shape is unsupported. Definition at line 2341 of file provsql.c.


|
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.
| constants | Extension OID cache. |
| quals | Root of the quals tree (OpExpr or BoolExpr), or NULL (in which case result is returned unchanged). |
| result | Provenance expression to wrap. |
| columns | Per-RTE column-numbering array. |
eq gates added. Definition at line 2417 of file provsql.c.


|
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.
| constants | Extension OID cache. |
| q | Query to modify in place. |
| provsql | Provenance expression that was added to the SELECT list. |
Definition at line 10186 of file provsql.c.

|
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.
| havingQual | Existing HAVING qualifier, or NULL. |
| expr | Expression to conjoin. |
Definition at line 10223 of file provsql.c.

|
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.
| q | Query to modify in place. |
| provenance | Expression to add (becomes the provsql output column). |
Definition at line 5738 of file provsql.c.


|
static |
Tree-mutator that replaces Aggrefs with provenance-aware aggregates.
| node | Current expression tree node. |
| ctx | Pointer to an aggregation_mutator_context (prov_atts, op, and constants). |
Definition at line 5290 of file provsql.c.


|
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.
| node | Current expression tree node. |
| ctx | Pointer to an aggregation_type_mutator_context (varno, varattno, and constants). |
Definition at line 295 of file provsql.c.


|
static |
Tree walker that detects any Var of type agg_token.
| node | Current expression tree node. |
| data | Pointer to a constants_t (extension OID cache). |
true if an agg_token Var is found in node. Definition at line 6768 of file provsql.c.


|
static |
|
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.
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.| q | Query whose range table is mapped. |
| columns | Pre-allocated array of length q->rtable->length. Each element is allocated and filled by this function. |
| nbcols | Out-param: total number of non-provenance output columns. |
Definition at line 10360 of file provsql.c.

|
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.

|
static |
Build the inner GROUP-BY subquery for one AGG(DISTINCT key).
Produces:
| q | Original query (supplies FROM / WHERE). |
| key_expr | The DISTINCT argument expression. |
| groupby_tes | Non-aggregate target entries that are GROUP BY columns. |
Query. Definition at line 4785 of file provsql.c.

|
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.


|
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.


|
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.

|
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.

|
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.

|
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.

|
static |
Wrap inner in an outer query that applies the original aggregate.
Produces:
The DISTINCT flag is cleared; inner provides exactly one row per (key, group-by) combination, so the plain aggregate gives the right count.
| orig_agg_te | Original TargetEntry containing AGG(DISTINCT key). |
| inner | Inner query from build_inner_for_distinct_key. |
| n_gb | Number of GROUP BY columns (trailing entries in inner). |
| constants | Extension OID cache. |
Query. Definition at line 4855 of file provsql.c.

|
static |
Walker: true if node (descending through nested queries) contains an explicit provenance() call.
Definition at line 6677 of file provsql.c.


|
static |
|
static |
|
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.
| node | Current expression tree node. |
| ctx | Pointer to the constants_t OID cache. |
Definition at line 5536 of file provsql.c.


|
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.

|
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.
| be | The Boolean expression to validate. |
| constants | Extension OID cache. |
Definition at line 10289 of file provsql.c.


|
static |
Top-level dispatcher for supported WHERE-on-aggregate patterns.
| expr | Expression to validate (OpExpr or BoolExpr). |
| constants | Extension OID cache. |
Definition at line 10321 of file provsql.c.


|
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; andOpExpr 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.


|
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.
| op | The OpExpr to inspect. |
| constants | Extension OID cache. |
Definition at line 10256 of file provsql.c.


|
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.


|
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.


|
static |
|
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.


|
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.


|
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.
Expr returning UUID; never NULL. Definition at line 2460 of file provsql.c.


|
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.


|
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.

|
static |
|
static |
|
static |
|
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.


|
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.

|
static |
|
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.


|
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.


|
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.


|
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.


|
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.
| constants | Extension OID cache. |
| q | Outer query to patch. |
| rteid | Range-table index of the subquery in q. |
| targetList | Target list of the subquery (to locate provenance_aggregate columns). |
Definition at line 350 of file provsql.c.


|
static |
|
static |
|
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.


|
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.
| probe | the (throwaway) query copy to flatten in place. |
| nflat_out | set to the flattened range-table length. |
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.


|
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.

|
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).| constants | Extension OID cache. |
| q | Query whose range table is scanned (subquery RTEs are modified in place by the recursive call). |
| in_boolean_rewrite | True when q lies under a safe-query (boolean) rewrite; threaded into the subquery recursion so the joint-width recogniser defers throughout the subtree. |
| inv_ctx | Inversion-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. |
Var nodes, one per provenance source; NIL if the query has no provenance-bearing relation. Definition at line 1985 of file provsql.c.


|
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):
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
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.


|
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).
| node | Expression tree to inspect. |
| constants | Extension OID cache. |
agg_token Var is found anywhere in node. Definition at line 6792 of file provsql.c.


|
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.
| constants | Extension OID cache. |
| q | Query to inspect. |
Definition at line 6494 of file provsql.c.


|
static |
|
static |
Tree walker that detects any provenance-bearing relation or provenance() call.
| node | Current expression tree node. |
| data | Pointer to constants_t (cast from void*). |
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.


|
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.
| be | Boolean expression from the HAVING clause. |
| constants | Extension OID cache. |
| negated | Whether the expression appears under a NOT. |
FuncExpr combining the sub-expressions. Definition at line 3346 of file provsql.c.


|
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.
| expr | Sub-expression to convert (BoolExpr or OpExpr). |
| constants | Extension OID cache. |
| negated | Whether the expression appears under a NOT. |
FuncExpr. Definition at line 3396 of file provsql.c.


|
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:
Var of type agg_token; orFuncExpr 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.


|
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.

|
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.


|
static |
Convert a comparison OpExpr on aggregate results into a provenance_cmp gate expression.
Each argument of opExpr must be one of:
Var of type agg_token (or a FuncExpr implicit-cast wrapper around one) → cast to UUID via agg_token_to_uuid.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.
| opExpr | The comparison expression from the HAVING clause. |
| constants | Extension OID cache. |
| negated | Whether the expression appears under a NOT. |
provenance_cmp(lhs, op_oid, rhs) FuncExpr. Definition at line 3009 of file provsql.c.


|
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.

|
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.


|
static |
|
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).
| rtable | Range table to scan for RTE_CTE entries. |
| cteList | CTE definitions to look up names in. |
| lowered | In/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.


|
static |
|
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.


|
static |
Is q a recorded inert provenance()-fetch subselect?
Definition at line 6258 of file provsql.c.

|
static |
|
static |
|
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.
| node | Expression tree to inspect. |
| constants | Extension OID cache. |
| rteid | Out: varno of the agg_token Var (unchanged on miss). |
| join_attno | Out: attno of the agg_token Var (unchanged on miss). |
OpExpr was found. Definition at line 10813 of file provsql.c.


|
static |
|
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.

|
static |
|
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.


|
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:
COUNT(*) and COUNT(expr) are remapped to SUM so that the semimodule semantics (scalar × token → token) work correctly.
| constants | Extension OID cache. |
| agg_ref | The original Aggref node from the query. |
| prov_atts | List of provenance Var nodes. |
| op | Semiring operation (determines how tokens are combined). |
| is_scalar | Aggregation has no GROUP BY (single always-present row). |
agg_token. Definition at line 2578 of file provsql.c.


|
static |
|
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.
| constants | Extension OID cache. |
| q | Owning query (needed to update permission info on PG 16+). |
| r | Range-table entry that owns the provenance column. |
| relid | 1-based index of r in q->rtable. |
| attid | 1-based attribute number of the provenance column in r. |
Var node. Definition at line 169 of file provsql.c.

|
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.
| constants | Extension OID cache. |
| q | Query being rewritten (HAVING is cleared if present). |
| prov_atts | List of provenance Var nodes. |
| aggregation | True if the query contains aggregate functions. |
| group_by_rewrite | True if a GROUP BY requires the plus-aggregate wrapper. |
| op | Semiring operation to use for combining tokens. |
| columns | Per-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). |
| nbcols | Total number of non-provenance output columns. |
| wrap_assumed | If true, wrap the result in assume_boolean so downstream probability evaluators may treat it as Boolean. |
| in_boolean_rewrite | True 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_cert | If 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. |
Expr to be appended to the target list. Definition at line 4253 of file provsql.c.


|
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.

|
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.


|
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+).
| arr_expr | Expression evaluating to uuid[]. |
| index | 1-based element position. |
| constants | Extension OID cache. |
uuid. Definition at line 10834 of file provsql.c.

|
static |
|
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.
| args | Argument list to inspect (modified in place). |
| parent_funcid | OID of the parent function / operator implementor. |
| constants | Extension OID cache. |
Definition at line 5386 of file provsql.c.


|
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:
| constants | Extension OID cache. |
| q | Query whose jointree->quals and havingQual may both be mutated in place. |
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.


|
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.


|
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.


|
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.


|
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.


|
static |
|
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.
| q | Query to normalise in place. |
Definition at line 5936 of file provsql.c.


|
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.


|
static |
|
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.


|
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.


|
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.


|
static |
|
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.


|
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.


|
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.

|
static |
|
static |
|
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.


|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
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.


|
static |
|
static |
|
static |
|
static |
|
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.

|
static |
|
static |
|
static |
|
static |
|
static |
|
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.


|
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.


|
static |
|
static |
|
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.

|
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.


|
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.


|
static |
|
static |
|
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.


|
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:
provsql column propagated into this query's target list.get_provenance_attributes.build_column_map).| constants | Extension OID cache. |
| q | Query to rewrite (modified in place). |
| removed | Out-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_root | If true, mark this query's provenance expression as a safe-query root that must be wrapped in provsql.assume_boolean before splicing. |
| top_level | True for the outermost query the user evaluates; gates the inversion-free analysis (run only at the top). |
| in_boolean_rewrite | True 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_ctx | Inversion-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. |
NULL if the query has no FROM clause and can be skipped. Definition at line 12105 of file provsql.c.


|
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.
| constants | Extension OID cache. |
| stmt | Root (or subtree) of the UNION SetOperationStmt. |
| q | Outer query (to look up subquery RTEs for agg_token type updates). |
Definition at line 10136 of file provsql.c.


|
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).
| constants | Extension OID cache. |
| q | Query to inspect. |
provenance() call. Definition at line 6136 of file provsql.c.


|
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.
| node | Current expression tree node. |
| data | Pointer to constants_t (cast from void*). |
true if a provenance() call is found anywhere in node. Definition at line 6111 of file provsql.c.


|
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.


|
static |
Tree-mutator that replaces provenance() calls with the actual provenance expression.
| node | Current expression tree node. |
| ctx | Pointer to a provenance_mutator_context (provenance expression and constants). |
Definition at line 5816 of file provsql.c.


|
static |
Map provsql_table_kind to its textual label (set_table_info accepts text).
Definition at line 13213 of file provsql.c.

|
static |
|
static |
|
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.
| q | The query to plan. |
| cursorOptions | Cursor options bitmask. |
| boundParams | Pre-bound parameter values. |
Definition at line 12863 of file provsql.c.


|
static |
|
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.


|
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.


|
static |
|
static |
|
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.


|
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.


|
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.


|
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.
| targetList | Target list of the outer query to patch. |
| varno | Range-table entry whose attribute numbers need fixing. |
| offset | Cumulative shift per original attribute (negative or zero). |
Definition at line 249 of file provsql.c.


|
static |
Tree-mutator callback that adjusts Var attribute numbers.
| node | Current expression tree node. |
| ctx | Pointer to a reduce_varattno_mutator_context. |
Definition at line 221 of file provsql.c.


|
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.
| q | Query to modify in place. |
| removed_sortgrouprefs | Bitmapset of ressortgroupref values to remove. |
Definition at line 5961 of file provsql.c.


|
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.
| q | Query containing setOperations. |
| removed | Boolean array (from remove_provenance_attributes_select) indicating which columns were removed. |
Definition at line 5998 of file provsql.c.


|
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.
| constants | Extension OID cache. |
| q | Query to modify in place. |
| removed | Out-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. |
ressortgroupref values whose entries were removed (so the caller can clean up GROUP BY / ORDER BY). Definition at line 2178 of file provsql.c.


|
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.


|
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).
| constants | Extension OID cache. |
| q | Query to mutate in place. |
| prov_atts | List of provenance Var nodes. |
| op | Semiring operation for combining tokens across rows. |
Definition at line 5690 of file provsql.c.


|
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.


|
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.
| constants | Extension OID cache. |
| q | Query to mutate in place. |
| provsql | Provenance expression to substitute. |
Definition at line 5871 of file provsql.c.


|
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.


|
static |
Rewrite every AGG(DISTINCT key) in q using independent subqueries.
For a single DISTINCT aggregate, produces a subquery:
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.
| q | Query to inspect and possibly rewrite. |
| constants | Extension OID cache. |
NULL if no AGG(DISTINCT) was found. Definition at line 5028 of file provsql.c.


|
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.


|
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.


|
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.


|
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:
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.
| q | Query to rewrite (modified in place). |
| constants | Extension OID cache. |
| rteid | 1-based varno of the RTE owning the agg_token column. |
| join_attno | 1-based attno of the agg_token column in that RTE. |
Definition at line 11015 of file provsql.c.


|
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.
| q | Query whose setOperations is non-ALL (modified to ALL in place). |
q as a subquery RTE. Definition at line 6039 of file provsql.c.

|
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.


|
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(*)<2 → P(=1) not P(≤1)).
Definition at line 9243 of file provsql.c.


|
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.


|
static |
Test whether funcoid is one of the random_variable_* comparison procedures, and if so return its ComparisonOperator index.
| constants | Extension OID cache. |
| funcoid | Procedure OID to test (typically OpExpr->opfuncid). |
[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.

|
static |
|
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.
| opExpr | The comparison expression from the WHERE clause. Must satisfy rv_cmp_index(opExpr->opfuncid) ≥ 0; callers are responsible for the type check. |
| constants | Extension OID cache. |
| negated | Whether the expression appears under a NOT. |
Definition at line 3497 of file provsql.c.


|
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.


|
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.


|
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.


|
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.


|
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.


|
static |
|
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.

|
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.
| q | Query to modify in place. |
Definition at line 5895 of file provsql.c.

|
static |
Rewrite an EXCEPT query into a LEFT JOIN with monus provenance.
EXCEPT cannot be handled directly because it deduplicates. This function transforms:
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.
| constants | Extension OID cache. |
| q | Query to rewrite in place. |
Definition at line 6916 of file provsql.c.


|
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):
*c (either side), unary -; avg also +c / -c.+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.


|
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.


|
static |
Wrap a provenance_aggregate FuncExpr with a cast to the original aggregate return type.
| prov_agg | The provenance_aggregate FuncExpr to wrap. |
| constants | Extension OID cache. |
prov_agg. Definition at line 5313 of file provsql.c.

|
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.

|
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.
| constants | Extension OID cache. |
| expr | Provenance expression to wrap. |
FuncExpr applying provsql.assume_boolean to expr. Definition at line 11368 of file provsql.c.

|
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.

|
static |
|
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.

|
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.

|
static |
|
static |
|
static |
| 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).
|
static |
| bool provsql_aggtoken_text_as_uuid = false |
| 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.
| 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.
| int provsql_dtree_max_subproblems = 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.
| 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).
| bool provsql_hybrid_evaluation = true |
|
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.
| bool provsql_interrupted = false |
| 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.
| int provsql_joint_max_states = 65536 |
| int provsql_joint_max_treewidth = 10 |
| bool provsql_joint_width = true |
| 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).
| 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.
| bool provsql_mobius = true |
| int provsql_mobius_max_gates = 4000000 |
| int provsql_monte_carlo_seed = -1 |
|
static |
|
static |
Option table of the provsql.provenance 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.
Default sample count for Monte Carlo fallbacks when an analytical evaluator (Expectation, future hybrid evaluator, ...) cannot decompose a sub-circuit structurally.
| 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).
| 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.
|
static |
| int provsql_verbose = 100 |