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

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

#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "pg_config.h"
#include "access/transam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_namespace.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/clauses.h"
#include "optimizer/tlist.h"
#include "optimizer/planner.h"
#include "access/heapam.h"
#include "parser/analyze.h"
#include "access/xact.h"
#include "utils/rel.h"
#include "parser/parse_agg.h"
#include "parser/parse_clause.h"
#include "parser/parser.h"
#include "parser/parse_coerce.h"
#include "parser/parse_node.h"
#include "parser/parse_oper.h"
#include "rewrite/rewriteManip.h"
#include "parser/parse_func.h"
#include "parser/parse_collate.h"
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "mb/pg_wchar.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 "utils/typcache.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_rmgr.h"
#include "provsql_shmem.h"
#include "provsql_utils.h"
#include "safe_query.h"
#include "compatibility.h"
Include dependency graph for provsql.c:

Go to the source code of this file.

Classes

struct  explode_col
 One column of a subquery to explode: where it is, and the type the values of its aggregate take. More...
struct  CteRefCtx
struct  reduce_varattno_context
 Context for the reduce_varattno_walker tree walker. More...
struct  aggregation_type_mutator_context
 Context for the aggregation_type_mutator tree walker. More...
struct  aggref_over_agg_token_ctx
 Context for aggref_over_agg_token_walker. More...
struct  LoweredCte
 Memo entry mapping a recursive-CTE name to its lowered scan subquery. More...
 Inline CTE references in q as subqueries where the rewrite needs them, preserving CTEs whose bodies need no rewriting. More...
struct  contains_agg_ctx
 Context for contains_agg_walker. More...
struct  deviation_ctx
 Context for deviation_mutator. 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  scalar_distinct_ctx
 Context for scalar_distinct_mutator. More...
struct  aggregation_mutator_context
 Context for the aggregation_mutator tree walker. More...
struct  window_aggregation_context
 Context for window_aggregation_mutator. More...
struct  provenance_mutator_context
 Context for the provenance_mutator tree walker. More...
struct  grouping_set_ctx
 Context for grouping_set_mutator. More...
 Context for sublink_over_tracked_walker. More...
 Context for sublink_classify_walker. More...
 A refusal cause: a stable tag for tooling, a sentence for a reader. More...
 Context of tracked_sublink_count_walker. More...
struct  freeze_rels_ctx
 Context for freeze_relations_walker. More...
struct  window_kinds_ctx
 Context for window_kinds_walker. More...
struct  holds_node_ctx
 Report an implicit freezing: a part of the statement evaluated as plain SQL on the data as it is, not tracked. More...
struct  agg_null_test_ctx
 State of agg_token_null_test_walker: the sort keys to pass over. More...
struct  count_cte_refs_ctx
 Context for count_cte_refs_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  moved_vars_ctx
 Context for moved_vars_mutator. More...
struct  oj_reads_ctx
 Context for oj_reads_rtindexes_walker. More...
struct  oj_syscol_ctx
 Lower an outer JOIN of two tracked arms into the UNION-ALL of its matched and null-padded antijoin arms. More...
struct  oj_decorr_ctx
 Mutator: lift a scalar subquery's body into the outer query level. More...
 Walker: count SubLink nodes (capturing the first), and capture a Var referencing varno target_varno (level 0) – used to find a Q column for the count() key. More...
struct  oj_sl_replace_ctx
 Mutator: replace the specific SubLink node target (by pointer) with replacement. More...
struct  oj_wrap_ctx
 Var-remap context for the FROM-wrapping pre-step: a Var at target_level on relation varno / attribute varattno is retargeted to newidx column pos[varno][varattno]. More...
struct  pull_up_vars_ctx
 Context for pull_up_vars_mutator. More...
struct  pull_up_vars_deep_ctx
 Context for pull_up_vars_deep_mutator. More...
struct  reads_outside_ctx
 Context for reads_outside_walker. More...
struct  oj_param_repl_ctx
 Context for oj_param_repl_mut. More...
struct  bool_exists_ctx
 Context of bool_exists_mutator. More...
struct  na_pair_ctx
 Where the relations of the source query land in the pair block: the ones of its own FROM keep their index, and the body's relation goes after them. More...
struct  uncorr_qual_ctx
 Context of uncorr_qual_sublink_mutator. More...
struct  tl_exists_ctx
 Context of tl_exists_mutator. More...
 Context for oj_replace_sublink_mut. More...
struct  retype_union_var_ctx
 Context for retype_union_var_mutator. 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  agg_nulltest_ctx
 Context for push_agg_nulltest_walker. More...
struct  subagg_read_ctx
 Whether q reads the value of an aggregate of one of its subqueries as data: a GROUP BY key, or a DISTINCT column. More...
struct  agg_cmp_truth_ctx
 Context of the search for a comparison to explode. More...
struct  agg_cmp_subst_ctx
 Replace every copy of ctx->found by the truth column's Var. 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  join_alias_ctx
 Rewrite a single SELECT query to carry provenance. More...
struct  renumber_rte_ctx
 Context for the rtindex-renumbering mutator of normalize_inner_joins. More...
struct  uncertain_value_ctx
 Context for uncertain_value_walker. More...
 Context for targetlist_sublink_mutator. More...
struct  outer_refs_ctx
 Walker context for outer_refs_are_keys_walker. More...
struct  wholerow_ctx
 Context for wholerow_mutator. More...
struct  agg_null_key_ctx
 Context for sort_key_reads_agg_null_walker. More...
struct  pull_aggregates_ctx
 Context for pull_aggregates_mutator. More...
struct  cume_dist_ctx
 Compute the aggregation of q in a subquery, and its windows over that subquery's columns. More...
struct  rank_window_ctx
 Context for replace_rank_window_mutator. More...
struct  src_var_type_ctx
 Walker context for collect_source_var_types. More...
struct  prov_read_ctx
 Context of reads_provsql_walker: the level whose range table resolves the Vars being looked at. More...
struct  agg_value_read_ctx
 Context for reads_agg_value_walker. More...
struct  ProvSQLCtasCapture
 State captured by the pre-execution pass for the post-execution one. More...
struct  rowstar_ctx
 Context for rowstar_mutator. More...

Macros

#define PROVSQL_DISTINCT_ALIAS   "provsql_distinct"
 Alias prefix of the subqueries rewrite_agg_distinct joins, one per AGG(DISTINCT x).
#define PROVSQL_EXPLODE_ALIAS   "provsql_agg_value"
 Alias of the lateral column an aggregate value is exploded into: one row per value the aggregate takes over the possible worlds (rewrite_explode_agg_value).
#define PROVSQL_TRUTH_ALIAS   "provsql_agg_truth"
 Alias of the two-row source the truth of a comparison of an aggregate explodes over (rewrite_explode_agg_cmp_truth).
#define PROVSQL_STAR_COLUMN_NAME   "provsql_star"
 Name the recursion lowering gives, in the rounds, to the provenance column a "SELECT *" put in a recursive CTE (neutralise_star_provenance).
#define PROVSQL_REC_PREFIX   "provsql_rec_"
 Prefix of the temporary tables the recursion lowering fills (rec_work_table_name).
#define PROVSQL_AGG_COUNT_COLNAME   "provsql_agg_count"
 Column of the companion count that gates the NULL value of an exploded aggregate (rewrite_explode_agg_value).
#define PROVSQL_DENSE_ALIAS   "provsql_dense_keys"
 Alias of the deduplicated keys a dense rank counts (make_dense_rank_subquery).
#define PROVSQL_MAX_SUBXACT_DEPTH   64
 provsql_executor_depth when each open subtransaction started, by nesting level, to restore it when the subtransaction aborts.
#define POSSIBLE_HI(bound)
#define POSSIBLE_LO(bound)
#define INT_ZERO()
#define PROVSQL_INERT_QUERY_ID   0x70727673 /* "prvs", fits every queryId type */
 The queryId marking an inert provenance()-fetch subselect (and its copies).
#define PROVSQL_JOIN_ALIAS   "provsql_join"
 Sentinel eref alias marking join RTEs that ProvSQL itself constructs (the EXCEPT antijoin, the sublink decorrelation): their monus construction accounts for the null-padded rows, so check_unlowered_outer_joins skips them.
#define PROVSQL_FLATTEN(n)
#define PROVSQL_MATCH_IND_COLNAME   "provsql_match_ind"
 Column name of the constant match indicator added by oj_wrap_body_with_match_ind.

Enumerations

enum  { PROVSQL_FREEZE_WARN , PROVSQL_FREEZE_ERROR }
 Values of provsql.implicit_freeze. More...
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 void provsql_xact_callback (XactEvent event, void *arg)
 Transaction callback: no executor runs between transactions.
static void provsql_subxact_callback (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
 Subtransaction callback: an aborted subtransaction (a PL/pgSQL exception block) leaves the executor depth it started at.
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)
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 expr_provably_not_null (Node *e, const Query *q, Index levelsup)
 Conservative provably-not-NULL test for the sublink lift.
static bool output_provably_not_null (const Query *sub, AttrNumber attno)
 Whether output column attno of subquery sub can never be NULL.
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 bool is_inert_subselect (Query *q)
 Is q a recorded inert provenance()-fetch subselect?
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 bool expr_is_aggregate_result (const constants_t *constants, Query *q, Node *e)
 Whether e, an expression of q, is the result of an aggregate: an agg_token, or, not rewritten yet, an aggregate of a subquery it reads or a subquery expression, through subqueries and joins.
static bool query_has_own_sublinks (Query *q)
 Whether a subquery expression remains in q's own clauses (its target list, conditions or HAVING): what hasSubLinks must say after a rewriting removed some, since the planner plans the subquery expressions only of a query that says it has some.
static Var * group_key_var (Query *q, TargetEntry *te)
 The column te groups by, or NULL if it is no plain column.
static Query * split_aggregation_into_subquery (Query *q)
 Compute the aggregation of q in a subquery, q keeping what reads its results.
static bool agg_column_explodable (const constants_t *constants, RangeTblEntry *rte, AttrNumber attno)
 Whether column attno of the subquery rte is the result of an aggregate that can be exploded into one row per value it takes.
static Query * rewrite_explode_agg_cmp_truth (Query *q, const constants_t *constants)
 Explode the truth of a comparison of an aggregate against a constant into the two rows its two truths give.
static Query * rewrite_explode_agg_values (Query *q, const constants_t *constants, Index rteid, List *cols)
 The aggregate columns cols of the subquery at rteid, each exploded into one row per value its aggregate takes over the possible worlds.
static bool node_varies_walker (Node *n, void *ctx)
 Does n hold a Var, an aggregate or a subquery – anything that is not the same in every row and every world?
static bool oj_contains_sublink_walker (Node *node, void *cx)
 Walker: true if the subtree contains the specific SubLink cx.
static bool has_aggtoken (Node *node, const constants_t *constants)
 Return true if node contains a Var of type agg_token.
static void report_freeze (const constants_t *constants, Node *frozen, const char *scope, const char *tag, const char *msg, const char *hint)
static bool cte_reference_walker (Node *node, void *context)
 Walker: does the tree contain an RTE_CTE reference to a CTE of the given name?
static bool rte_column_is_aggregate (const constants_t *constants, RangeTblEntry *rte, AttrNumber attno)
 Whether column attno of the subquery rte is an aggregate result: its entry is an aggregate, or the agg_token it becomes once the subquery is rewritten.
static bool distinct_on_lowerable (const constants_t *constants, Query *q)
 Whether the DISTINCT ON of q is rewritten into the filter of a rank (lower_distinct_on_to_rank): a query that keeps its input rows, keys and order on values that are the same in every world.
static Node * make_null_safe_equality (Expr *l, Expr *r, Oid type, Oid collation, bool nullable)
 Build a comparison of l and r under which two NULLs are equal.
static bool expr_contains_aggref (Node *node)
 Whether an expression contains a plain Aggref.
static void hide_provsql_in_wholerows (const constants_t *constants, Query *q, bool top_level)
 Leave the provsql column out of the whole-row values of provenance-tracked relations where any row is read.
static bool has_rv_or_provenance_call (Node *node, void *data)
 Tree walker that detects any provenance-bearing relation or provenance() call.
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 bool reduce_varattno_walker (Node *node, void *ctx)
 Tree-walker callback that adjusts Var attribute numbers, in place.
static void reduce_varattno_by_offset (Query *q, Index varno, int *offset)
 Adjust Var attribute numbers in q 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 * 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 Node * frozen_agg_value (Node *arg, Oid target_type, const constants_t *constants)
 The value of the agg_token arg as a target_type, read by ProvSQL where the query reads a plain value.
static Node * plain_agg_value (Node *arg, Oid target_type, const constants_t *constants)
 The value of the agg_token arg as a target_type, read where the query ASKED for the plain value with plain().
static bool takes_agg_token (Oid funcid, int i, const constants_t *constants)
 Whether argument i of function funcid takes an agg_token as it is: a parameter of type agg_token, or a polymorphic one of a ProvSQL function (expected(cnt), sr_formula(cnt, ...)).
static Node * aggregation_type_mutator (Node *node, void *ctx)
 Tree-mutator that retypes a specific Var to agg_token.
static bool agg_token_var_walker (Node *node, void *context)
 expression_tree_walker predicate: some Var below node has type agg_token.
static Oid orig_agg_arg_of_var (Query *q, Var *v, const constants_t *constants, int depth, int argno)
 orig_agg_arg_of_column for a Var of q, or InvalidOid.
static bool reaggregates_agg_result (const constants_t *constants, Query *q, Aggref *agg)
 Whether the aggregate agg of query q reads an aggregate result of a subquery that it aggregates again as the rows of their groups.
static bool nested_agg_trackable (const constants_t *constants, Query *q, Aggref *agg)
 Whether the aggregate agg of an aggregate result of another kind can be tracked per possible world.
static bool freeze_agg_token_args (Aggref *agg, const constants_t *constants)
 Read the inner aggregate's value as a plain value inside agg: replace each agg_token argument by its frozen value, of the type the aggregate was resolved on.
static bool aggref_over_agg_token_walker (Node *node, void *context)
 expression_tree_walker noting an Aggref whose arguments read an agg_token column: an aggregate of an aggregate result from a subquery (max of a count, avg of a sum...) that is no pair the reaggregation carries (reaggregates_agg_result) reads the inner value as a plain value, reported once per statement, rather than refusing the statement.
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 bool query_references_cte (Query *q, const char *name)
 Does q (at any depth) reference a CTE named name?
static void inline_ctes_in_rtable (List *rtable, List *cteList, List **lowered, List *kept)
 Inline CTE references as subqueries within a query.
static bool inline_ctes_in_sublinks_walker (Node *node, void *cx)
 Walker: inline the CTE references of the subqueries of sublinks (IN, EXISTS, scalar subqueries), at any depth.
static bool cte_is_data_modifying (const CommonTableExpr *cte)
static void inline_ctes (const constants_t *constants, Query *q)
static List * get_provenance_attributes (const constants_t *constants, Query *q, bool in_boolean_rewrite, bool top_level, 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_cond (const constants_t *constants, Node *quals, Expr *result, int **columns, Expr *cond)
 Walk a join-condition or WHERE quals node and add eq gates for the column equalities that make the row an answer.
static Expr * add_eq_from_Quals_to_Expr (const constants_t *constants, Node *quals, Expr *result, int **columns)
 add_eq_from_Quals_to_Expr_cond for quals that always apply.
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 Aggref * build_rv_sum_aggref (const constants_t *constants, Oid aggfnoid, Expr *arg, Expr *filter)
 Build an Aggref for an RV-summing aggregate over arg.
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, baking each aggregate's identity element into the per-row provenance wrap.
static bool aggregate_keeps_nulls (const constants_t *constants, Oid aggfnoid)
 Whether a NULL input is part of what aggregate aggfnoid sees.
static Expr * make_case_when (Expr *cond, Expr *then_expr, Expr *else_expr)
 Build "CASE WHEN cond THEN then_expr [ELSE else_expr] END".
static Expr * make_row_token (const constants_t *constants, List *prov_atts, semiring_operation op)
 The provenance token of the current row: its single provenance attribute, or their product (SR_TIMES) or difference (SR_MONUS).
static FuncExpr * make_row_semimod (const constants_t *constants, Oid aggfnoid, Expr *arg, Expr *filter, Expr *row_token)
 The contribution of the current row to an aggregate gate: provenance_semimod of the value it adds and of its token.
static Expr * make_aggregation_expression (const constants_t *constants, Query *q, Aggref *agg_ref, List *prov_atts, semiring_operation op, bool is_scalar, Expr *plain_token)
 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 bool having_entails_group_existence (Expr *expr, const constants_t *constants, bool negated)
 Whether a lifted HAVING predicate already entails that the group exists.
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)
static Node * try_swap_agg_func (FuncExpr *f, const constants_t *constants)
 The agg_token counterpart of a function over an aggregate result, or NULL where there is none.
static FuncExpr * agg_expr_null_gate (Node *arg, const constants_t *constants, bool want_null)
static Node * try_lower_agg_case (Node *node, const constants_t *constants)
 A CASE over aggregates, or what becomes one (GREATEST / LEAST, COALESCE, NULLIF), lowered to its agg_case gate.
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 List * operator_name (const char *op, Oid ltype, Oid rtype)
 The name of operator op between types ltype and rtype (InvalidOid for a prefix operator's left side), for a lookup.
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 Node * strip_agg_cast (Node *n)
 Strip one cast layer around an aggregate: a single-argument cast (the agg_token -> numeric cast the aggregate-lowering pass wraps, a cast the parser inserted), or the value of an aggregate read through its text (frozen_agg_value).
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 *K, Expr *cond)
 Build "⊕(array_agg(K) FILTER (WHERE cond))" – the per-row provenance ⊕ over the rows of an aggregate's group that satisfy cond.
static FuncExpr * uuid_const_gate (Oid funcid, const constants_t *constants)
 A no-argument gate constructor – gate_one(), gate_zero().
static FuncExpr * uuid_nary_gate (Oid funcid, List *elements, const constants_t *constants)
 provenance_plus / provenance_times over elements, each a UUID-valued gate expression, as the variadic call over an array the SQL functions take.
static FuncExpr * uuid_complement (Node *gate, const constants_t *constants)
 "𝟙 ⊖ gate", the complement of a Boolean gate.
static bool aggregate_null_has_reading (Oid aggfnoid, const constants_t *constants)
 Whether the NULL-ness of an aggregate of this kind has a reading at all: what having_NullTest_to_provenance builds a gate for, and what the guards of a lowered CASE may therefore ask.
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 * divisor_zero_gate (Node *divisor, const constants_t *constants, bool want_zero)
 The gate of "expr IS NULL" (want_null) or of "expr IS NOT NULL", where arg is an expression over aggregates rather than an aggregate itself.
static List * agg_token_division_args (Node *node, const constants_t *constants)
 The arguments of a division over agg_token, or NIL.
static FuncExpr * agg_arith_strict_null_gate (List *args, List *div_args, const constants_t *constants, bool want_null)
 The gate of "expr IS [NOT] NULL" for an arithmetic expression over agg_token, strict in every operand of args.
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 Aggref * aggref_over_all_rows (Aggref *ar, const constants_t *constants)
 The original Aggref behind the aggregate side of a comparison, or NULL if node is not a lowered aggregate of this query level.
static Aggref * having_side_aggref (Node *node, const constants_t *constants)
static Aggref * aggref_with_filter (Aggref *ar, Expr *cond)
 Copy of ar with cond ANDed to its FILTER clause.
static Aggref * oj_make_aggref (Oid aggfnoid, Oid aggtype, Oid argtype, Expr *arg)
 Build an Aggref for a single-argument aggregate.
static Oid builtin_aggregate (const char *name, Oid argtype)
 The built-in aggregate name over argtype, or InvalidOid.
static Node * to_numeric (Node *n)
 n as numeric, where it is not one already.
static Node * deviation_as_arithmetic (Aggref *ar, const constants_t *constants)
 stddev / variance of ar as the arithmetic over sum, sum of squares and count that defines it, or NULL.
static Aggref * aggref_sibling (Aggref *ar, const char *name)
 Copy of ar computing the built-in aggregate name ("min" or "max") of the same argument, or NULL if there is none declared on exactly that argument type.
static Expr * or_exprs (Expr *a, Expr *b)
 "a OR b", either of which may be NULL (absent).
static bool agg_func_carried (const char *name)
 Whether the comparison op of an aggregate with an aggregate-free term may hold in some world; NULL when nothing is known.
static Node * having_int_const (int32 v)
 The int4 constant v, for a bound this relaxes by one.
static OpExpr * having_reuse_op (OpExpr *op, Oid opno, Node *agg_side, Node *c, bool agg_on_left)
 op with its two arguments replaced, the same operator.
static Expr * having_possible_atom (OpExpr *op, const constants_t *constants, bool negated)
static Expr * having_possible_carried (OpExpr *op, const constants_t *constants, bool negated, bool *handled)
 The PostgreSQL-evaluable necessary condition of a comparison whose aggregate side is read by a function ProvSQL carries (floor, ceil, round, abs), or NULL where there is none.
static Expr * having_possible (Expr *expr, const constants_t *constants, bool negated)
 Condition under which the HAVING predicate expr may hold in some world, or NULL when nothing is known (it may always hold).
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 bool is_null_constant_operand (Node *node)
 True when node is a NULL constant (through a coercion).
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 bool case_has_rv_cmp (CaseExpr *ce, const constants_t *constants)
 Does a searched CASE have at least one RV-comparison guard?
static Node * build_rv_case (CaseExpr *ce, const constants_t *constants)
 Lower an RV-typed searched CASE into a rv_case(...) call.
static bool node_is_agg_token (Node *n, const constants_t *constants)
static Node * agg_arm_to_uuid_or_null (Node *arm, const constants_t *constants)
static Node * agg_arm_to_uuid (Node *arm, const constants_t *constants)
static bool case_is_agg_carrier (CaseExpr *ce, const constants_t *constants)
static Node * build_agg_case (CaseExpr *ce, const constants_t *constants)
static CaseExpr * coalesce_agg_to_case (CoalesceExpr *co, const constants_t *constants)
 COALESCE(aggregate, default) as the searched CASE it means.
static Node * bool_agg_to_int_case (Node *agg, const constants_t *constants)
 A Boolean aggregate cast to an integer, as the searched CASE that cast means.
static CaseExpr * nullif_agg_to_case (NullIfExpr *ni, const constants_t *constants)
 NULLIF over an aggregate as the searched CASE it means.
static Node * peel_agg_token_arm (Node *n, const constants_t *constants)
 GREATEST / LEAST of two arguments as the searched CASE it means.
static CaseExpr * minmax_agg_to_case (MinMaxExpr *mm, const constants_t *constants)
static Node * rewrite_agg_case_mutator (Node *node, void *context)
static Node * deviation_mutator (Node *node, void *cx)
 Mutator: each stddev / variance as the arithmetic it is.
static void rewrite_deviation_aggregates (const constants_t *constants, Query *q)
 Read every stddev / variance of q as the arithmetic over sum, sum of squares and count that defines it.
static void rewrite_agg_cases (const constants_t *constants, Query *q)
static bool is_projected_rv_event (Node *node, const constants_t *constants)
 Is node a projected random_variable comparison event?
static Node * rewrite_probability_event_mutator (Node *node, void *data)
 Mutator: lift the RV surface that can appear in the target list.
static Node * lift_rv_event_mutator (Node *node, void *data)
 Mutator: lift any random_variable comparison event to its token.
static void rewrite_probability_events (const constants_t *constants, Query *q)
 Lift RV-comparison events in q's target list into their tokens.
static void rewrite_dml_rv_surface (const constants_t *constants, Query *q)
 Lower the RV surface in the values a data-modifying statement supplies directly.
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 Node * scalar_distinct_mutator (Node *node, void *cx)
 Mutator: renumber the Vars on the outer subqueries of rewrite_agg_distinct, and replace each remaining aggregate by a Var on the subquery computing it.
static void scalar_distinct_as_cross_join (Query *q, int base, int n)
 Turn the scalar query q rewritten by rewrite_agg_distinct into a cross join of one-row subqueries.
static bool agg_distinct_args_supported (Aggref *ar)
 Can ar, an AGG(DISTINCT), be computed over the distinct values of its first argument?
static Query * rewrite_agg_distinct (Query *q, const constants_t *constants)
 Rewrite every AGG(DISTINCT key) in q using independent subqueries.
static bool token_may_be_false (const constants_t *constants, Query *q, Node *e)
 Whether a provenance expression of q may be false in the database as it is, every input tuple present.
static bool rv_cmp_walker (Node *node, void *ctx)
 The row token a displayed aggregate value is filtered by, or NULL when every row of q holds in the database as it is.
static Expr * plain_row_token (const constants_t *constants, Query *q, List *prov_atts, semiring_operation op)
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 Oid formal_arg_type (Form_pg_proc procForm, int i)
 The type of parameter i of a function, provariadic for the arguments a VARIADIC parameter spreads over (json_build_object's "any"), or InvalidOid.
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 * peel_widening_agg_cast (Node *n, const constants_t *constants)
 Rebuild an arithmetic operator over an aggregate so the result stays an agg_token (provenance preserved).
static Node * agg_arith_numeric_operand (Node *n)
 The operand an agg_token operator can be given, as numeric.
static bool pending_agg_case_walker (Node *n, void *cx)
 Tree-mutator that casts provenance_aggregate results back to the original aggregate return type where needed.
static Node * cast_agg_token_mutator (Node *node, void *ctx)
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 bool window_frame_by_values (const WindowClause *wc)
 Whether the frame of a window is determined by the values of the rows, not by their positions.
static bool window_frame_has_current_row (const WindowClause *wc)
 Whether every frame of a window contains its current row.
static WindowClause * window_clause_of (Query *q, Index winref)
 The WindowClause of q with reference winref.
static Expr * make_window_aggregation_expression (const constants_t *constants, Query *q, WindowFunc *wf, List *prov_atts)
 The provenance expression of an aggregate used as a window function, or NULL if it is not tracked.
static WindowFunc * make_rank_window (Query *q, WindowFunc *wf)
 The number of rows strictly before the current one, as the aggregate count(*) over a window.
static Expr * make_rank_expression (window_aggregation_context *c, WindowFunc *wf)
 The provenance expression of the rank of a row in the window of wf, 1 + the number of rows strictly before it, or NULL.
static Expr * make_dense_rank_expression (window_aggregation_context *c, WindowFunc *wf)
 The provenance expression of the dense rank of a row in the window of wf, 1 + the number of distinct ordering values strictly before it, or NULL.
static Node * window_aggregation_mutator (Node *node, void *ctx)
static bool windowfunc_outside_plain_walker (Node *node, void *cx)
 Replace the window functions of q's target list by their provenance expressions, where they have one.
static bool replace_window_aggregations (const constants_t *constants, Query *q, List *prov_atts)
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 void flatten_union_descendants (Node *node)
 Make every UNION reachable from node through UNION nodes an ALL.
static Index set_operation_leftmost_leaf (Node *node)
 Range-table index of the leftmost leaf of a set-operation tree.
static void set_operation_move_leaves (Node *node, List *old_rtable, List **rtable)
 Move the leaves of node into rtable, renumbering them.
static Query * set_operation_as_query (SetOperationStmt *stmt, List *old_rtable)
 Turn the set-operation subtree stmt into a query of its own.
static Query * intersect_side (Node *node, List *rtable)
 A side of an INTERSECT, as a subquery: a leaf, or a set operation made a query of its own.
static Expr * intersect_column (Query *side, Index varno, AttrNumber attno, Oid type, int32 typmod)
 Column attno of the side side (range-table entry varno), coerced to the type of the column of the set operation.
static Query * rewrite_intersect (const constants_t *constants, Query *q)
 Rewrite an INTERSECT into the deduplicated join of its sides.
static Query * union_all_of_arms (Query *q, List *arms)
 The UNION ALL of arms, each a variant of q exposing every entry of its target list, under an outer query that keeps the entries of q, its DISTINCT, ORDER BY and LIMIT.
static Node * grouping_set_mutator (Node *node, void *cx)
 Mutator: the value of an expression in the rows of one grouping set.
static Query * rewrite_grouping_sets (Query *q)
 Rewrite a GROUP BY with GROUPING SETS, ROLLUP or CUBE into the UNION ALL of one GROUP BY per set.
static bool nest_set_operations_rec (Node **nodep, SetOperationStmt *parent, List *old_rtable, List **rtable)
 Nest the set-operation subtrees that the rewriting cannot take in place, each as a subquery leaf.
static bool nest_set_operations (Query *q)
 Entry point of nest_set_operations_rec for the query q.
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 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 body_reads_tracked_cte (const constants_t *constants, List *ctes, Query *body)
 Whether body reads a WITH entry of ctes that is tracked.
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 oj_wrap_body_with_match_ind (const constants_t *constants, Query *sub)
 Wrap a NULL-guarded antijoin body into a derived subquery D carrying a constant match-indicator column.
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 sublink_reason sublink_reason_of (const char *scope, const char *tag, const char *msg)
 Build a sublink_reason.
static bool tracked_sublink_count_walker (Node *node, void *cx)
 Walker: count the sublinks over a tracked relation, one by one (not one per clause), without descending into one that is already counted.
static bool reads_outside_walker (Node *node, Index depth)
 Why a tracked sublink of q could not be rewritten.
static sublink_reason sublink_unsupported_reason (const constants_t *constants, Query *q, SubLink *sl)
static List * classify_remaining_sublinks (const constants_t *constants, Query *q, bool *has_direct, SubLink **offender)
 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 bool reads_token_walker (Node *node, void *data)
 Walker: a provsql column or a provenance() call.
static bool mark_plain_inner_walker (Node *node, void *cx)
 Walker: tag the subqueries of subquery expressions in node.
static bool mark_plain_sublinks_walker (Node *node, void *cx)
 Walker: mark the subquery expressions inside a plain() call as inert, evaluated as plain SQL (PROVSQL_INERT_QUERY_ID).
static bool rewrite_plain_from_walker (Node *node, void *cx)
 Walker: replace each FROM item plain(v), v a value of the row type of a table, by a subquery reading that table as plain SQL.
static void hide_plain_provsql_columns (Query *q)
 Hide, in the target list of q, the entries reading the provenance placeholder of a plain(NULL::t) source (the provsql column of a *): made junk, moved last, so that the other columns keep their positions.
static bool freeze_relations_walker (Node *node, void *cx)
 Walker: the base relations of the tracked relations read in a tree, but in ctx->skip.
static bool window_outside_fragment (Query *q, WindowFunc *wf)
 Walker: a window function outside any plain() call.
static bool window_kinds_walker (Node *node, void *cx)
 Walker: which kinds of untracked window function q holds.
static bool unmarked_window_walker (Node *node, void *cx)
static bool holds_node_walker (Node *node, void *cx)
 Walker: is target one of the nodes of the tree, by address?
static bool frozen_agg_value_walker (Node *node, void *cx)
 Walker: a value of an aggregate result read by ProvSQL as a plain value (frozen_agg_value), at any level.
static bool sortgroupref_is_sort_key (Query *q, Index ref)
 Whether ref is ordered by, or by a window of, q.
static bool agg_token_null_test_walker (Node *node, void *cx)
 Walker: a NULL test left ON an agg_token, which reads the aggregate's nullness in the database as it is.
static bool tracked_value_sublink_walker (Node *node, void *data)
 Walker over the expressions of one query level: a sublink whose body reads a tracked relation for its data.
static bool untracked_level_with_tracked_sublink_walker (Node *node, void *data)
 Walker: a query level the rewriting does not engage on (has_provenance) that has a subquery expression reading tracked data.
static bool count_cte_refs_walker (Node *node, void *cx)
 Walker: count the references to a CTE of an enclosing query.
static bool recount_cte_refs_walker (Node *node, void *cx)
 Walker: set the reference count of every CTE to the number of its references in the rewritten query.
static bool reset_varnoold_walker (Node *node, void *cx)
 Walker: reset varnoold / varoattno of every Var to its varno / varattno.
static bool tracked_sublink_remains_walker (Node *node, void *data)
 Walker over a rewritten query: a sublink, at any level, whose body still reads a tracked relation for its data.
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 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 Expr * except_arm_column (RangeTblEntry *rte, Var *arg, Var *v)
 arg, a column of the EXCEPT arm rte, with the type of that column, coerced to the type of the set operation's column v.
static bool except_column_is_aggregate_result (const constants_t *constants, RangeTblEntry *rte, AttrNumber attno)
 Whether column attno of the EXCEPT arm rte is the result of an aggregate (expr_is_aggregate_result): not compared, the other columns determining it.
static bool transform_except_into_join (const constants_t *constants, Query *q)
 Rewrite a difference node 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 RangeTblEntry * oj_copy_rel (Query *outer, Query *sub, RangeTblEntry *orig, int depth)
 Copy an outer-join arm RTE into the range table of subquery sub, depth levels below outer.
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, int depth)
 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, int depth)
 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 jointree_arm_has_tracked (const constants_t *constants, Query *q, Node *n)
 Walker: does the jointree fragment n reference a provenance-tracked RTE of q?
static void check_unlowered_outer_joins (const constants_t *constants, Query *q, Node *n)
 Refuse outer joins that survived lower_outer_joins with a provenance-tracked relation on a null-padded side.
static void flatten_join_aliases (Query *q)
 Replace the Vars of join RTEs in the expressions of q by the columns of the joined relations (before PostgreSQL 13, the parser builds a column read through a join as a Var of the join).
static void join_tree_rtindexes (Node *n, Bitmapset **idx)
 Collect the range-table indexes of a join tree (its relations and its joins).
static void make_placeholder_rte (RangeTblEntry *rte)
 Make rte an empty placeholder: an entry of the range table no longer read (its relation moved to a subquery), which must neither be scanned nor count as a source of provenance.
static bool is_provsql_column_var (List *rtable, Var *v)
 Whether v, a Var of range table rtable, is the provsql column of its relation: a subquery exposing it keeps that name, so that it drops it as any provenance column of its target list.
static Node * moved_vars_mutator (Node *node, void *cx)
 Mutator: a Var of a moved relation becomes a Var of the subquery's column exposing it, at any depth.
static void wrap_join_tree (Query *q, Node **slot)
 Move the join tree *slot of q into a subquery, which takes its place.
static bool join_tree_has_outer_join (Node *n)
 Whether n is a join tree containing an outer join.
static void oj_jointree_rtindexes (Node *jtnode, Bitmapset **idx)
 Collect into idx the range-table indexes jtnode reads.
static bool oj_reads_rtindexes_walker (Node *node, oj_reads_ctx *ctx)
 Walker: a Var of level sublevels_up reading one of idx.
static bool oj_lateral_reads_join (RangeTblEntry *r, Bitmapset *idx)
 Whether the LATERAL entry r reads a row of idx, the entries of the outer join that lower_outer_joins moves into a subquery.
static bool normalize_outer_join_tree (const constants_t *constants, Query *q)
 Bring the outer joins of q to the shape lower_outer_joins lowers: one outer join of two range-table entries as the whole FROM.
static bool oj_syscol_walker (Node *node, void *cx)
 Walker: does any Var read a whole row (varattno 0) or a system column (varattno < 0, ctid, xmin, ...) of either arm of the outer join being lowered?
static bool lower_outer_joins (const constants_t *constants, Query *q)
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 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 Aggref * oj_make_count_distinct (Expr *valexpr)
 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 OpExpr * oj_count_distinct_cmp (Expr *valexpr, const char *opstr, int64 n)
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 Node * pull_up_vars_mutator (Node *node, void *cx)
 Mutator: replace each Var of level 0 by a reference to an entry of ctx->inner exposing it, appended if needed.
static Node * pull_up_vars_deep_mutator (Node *node, void *cx)
 Mutator: pull_up_vars_mutator, also for the Vars of the query that nested queries (subquery expressions) read from one or more levels down.
static bool reads_outside_walker_rec (Node *node, void *cx)
 Walker: a reference (a Var, a CTE) to a query above the one the walk started in, depth levels up counting from there.
static bool lift_body_outer_only_conjuncts (Query *sub)
 Lift the conjuncts of an inner sublink body's WHERE that read nothing of that body's own relations into the qual holding the sublink.
static bool wrap_body_sublinks (Query *sub)
 Move the subquery tests of the WHERE of a subquery body sub into a derived table of it.
static bool wrap_body_grouping (const constants_t *constants, Query *sub)
 Move a sublink body that groups rows of its own into a derived table, so that what is left outside is the existence test the decorrelation already lowers.
static bool wrap_body_setop (const constants_t *constants, Query *sub)
 A sublink body that is a set operation becomes a derived table the semijoin reads.
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 bool type_has_equality (Oid type)
 Does type have a default equality operator?
static Expr * expr_as_text (Expr *e)
 e as text, through its output function.
static Node * extract_quantified_corr (SubLink *sl, bool *antijoin, bool neg, const Query *outerq, bool *guarded)
 Build the per-row correlation for a quantified sublink (IN / op ANY / op ALL), setting *antijoin.
static bool drop_semijoin_distinct_walker (Node *node, void *cx)
 Walker: drop the DISTINCT of the bodies of EXISTS, IN and quantified-comparison subqueries.
static Node * bool_exists_mutator (Node *node, void *cx)
 Rewrite the EXISTS of a Boolean combination into the count of its body.
static RangeTblEntry * na_body_relation (Query *b, bool allow_sublink)
 The single relation of b, where b is a body this pass can read: one base relation in its FROM, nothing else of its own.
static SubLink * na_not_exists (Node *n)
 The NOT EXISTS SubLink of n, or NULL.
static Node * na_corr_out_mut (Node *node, void *cx)
 Mutator for the body's own correlation, one level below the query: what reads the body's relation (level 0, its only one) becomes p_new of the pair block, and what reads the query's own relations comes down a level, keeping the index it had – the pair block holds them at the same places.
static Node * na_corr_in_mut (Node *node, void *cx)
 Mutator for the inner body, which keeps its level (one below the pair block): what read the body's relation and the query's own two and three levels up now read the block just above.
static RangeTblEntry * na_copy_rel (Query *to, Query *from, RangeTblEntry *src)
 Copy the relation entry src of from into to, with its permission info.
static Node * na_not_distinct (Expr *l, Expr *r)
 "l IS NOT DISTINCT FROM r".
static Query * na_except_to_nested (const constants_t *constants, Query *sub)
 Read a "NOT EXISTS (A EXCEPT B)" body as the nested antijoin it is, and return the body to read in its place, or NULL.
static bool rewrite_nested_antijoin (const constants_t *constants, Query *q)
 Read a nested antijoin as the antijoin of the query's own rows against the projection of its bad pairs (see the block comment above).
static bool rewrite_predicate_sublinks (const constants_t *constants, Query *q)
 Rewrite top-level EXISTS / IN WHERE conjuncts (optionally negated) over tracked relations 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_collect(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 * tracked_cte_of (const constants_t *constants, List *ctes, const RangeTblEntry *r)
 Build the derived single-row aggregate D for an UNcorrelated scalar subquery body, to be cross-joined into the outer FROM.
static bool query_is_scalar_aggregation (const Query *cq)
 Whether cq is one row in every possible world: a bare aggregate, which is defined over no row as well as over some.
static Query * oj_build_uncorrelated_from_subquery (const constants_t *constants, Query *body, List *ctes)
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 Node * uncorr_qual_sublink_mutator (Node *node, void *cx)
 Replace an uncorrelated scalar subquery of a qual by a column of the one-row derived table it becomes.
static Node * unc_membership_lhs (Node *node, SubLink **sl_out)
 The left side of a top-level membership test "lhs IN (body)" whose body reads nothing outside it, or NULL.
static bool unc_from_has_non_relation (Query *q)
 Does q read something in its FROM that is not a base relation?
static Node * unc_membership_to_join (const constants_t *constants, Query *q, Node *conj)
 Read an uncorrelated membership test as a join against the values of its body, deduplicated: "x IN (SELECT k FROM B WHERE p)" becomes "…, (SELECT DISTINCT k FROM B WHERE p) v WHERE x = v.k".
static bool wrap_untracked_from_for_sublink (const constants_t *constants, Query *q)
 Give a block whose FROM reads no tracked relation a carrier for the provenance its condition has: a certain provenance column on the untracked source.
static bool rewrite_uncorrelated_membership (const constants_t *constants, Query *q)
 Read every uncorrelated membership test of q as a join against the deduplicated body, where the block's own FROM holds something that is not a base relation.
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 oj_is_arith_opexpr (Node *node)
 Is node a binary/unary +,-,*,/,^,@ operator expression?
static bool is_comparison_opno (Oid opno)
 Is opno one of the six comparison operators by name?
static bool oj_tl_sublink_in_arith (Node *node, SubLink *sl)
 Is SubLink sl reachable from node through arithmetic only?
static Node * tl_exists_mutator (Node *node, void *cx)
 Rewrite an EXISTS of the select list into the count of its body.
static bool rewrite_target_list_exists (const constants_t *constants, Query *q)
 Rewrite the EXISTS values of q's select list (tl_exists_mutator).
static Node * oj_replace_sublink_mut (Node *node, void *cx)
 Replace one specific SubLink node with repl, in place.
static bool decorrelate_scalar_sublinks (const constants_t *constants, Query *q)
 Decorrelate scalar subqueries into a LEFT JOIN with grouping.
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 union_leaves (Node *n, List **leaves)
 The range-table indexes of the leaves of a set-operation tree.
static void set_union_column_type (Node *n, int i, Oid type)
 Set the type of column i on every node of a set-operation tree.
static Node * retype_union_var_mutator (Node *node, void *cx)
 Mutator: retype the Vars of one column of a set operation.
static void reconcile_union_columns (const constants_t *constants, SetOperationStmt *stmt, Query *q)
 Give each column of a UNION one type across its arms, once their aggregates have become agg_token.
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 orig_agg_arg_of_column (Query *sub, AttrNumber attno, const constants_t *constants, int depth, int argno)
 The aggregate function (argno 0) or the type (argno 1) of the aggregate an agg_token column of sub comes from, or InvalidOid.
static Oid orig_agg_type_of_var (Query *q, Var *v, const constants_t *constants, int depth)
 The type of the aggregate an agg_token Var of q comes from (orig_agg_arg_of_column), or InvalidOid.
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 bool agg_token_var_of_stored_relation (Var *v, insert_agg_token_casts_context *ctx)
 Whether v reads an agg_token column of a stored relation, rather than one this statement computes (a subquery's aggregate).
static void cast_agg_token_in_list (ListCell *lc, insert_agg_token_casts_context *ctx, bool through_text, Oid fallback)
 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, Oid fallback)
 Wrap any agg_token Vars in an argument list.
static bool case_test_type_walker (Node *node, void *cx)
 Walker: the type of the first CaseTestExpr below node.
static Oid case_test_type (List *whens)
 The type of the tested value of a simple CASE, as its WHEN comparisons read it, or InvalidOid.
static Node * cast_agg_token_node (Node *n, Oid type, insert_agg_token_casts_context *ctx)
 Cast one agg_token expression read as a value of type type: a subquery's aggregate column to its own type (else type), any other agg_token to type.
static void cast_agg_token_func_args (List *args, Oid funcid, insert_agg_token_casts_context *ctx)
 Cast the agg_token arguments of an operator or function that reads values.
static Node * insert_agg_token_casts_mutator (Node *node, void *data)
 Insert agg_token casts for Vars used in expressions.
static Node * insert_having_agg_token_casts_mutator (Node *node, void *data)
 insert_agg_token_casts_mutator for the HAVING clause.
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 bool contains_aggref_walker (Node *node, void *found)
 Walker for expr_contains_aggref.
static TargetEntry * agg_nulltest_target (Query *q, NullTest *nt, const constants_t *constants, Query **sub_out)
 The subquery target entry an IS [NOT] NULL is testing, if it is an aggregate of a subquery in q.
static bool push_one_agg_nulltest (NullTest *nt, agg_nulltest_ctx *ctx)
 Move one IS [NOT] NULL conjunct into its subquery's HAVING.
static Query * push_agg_nulltest_into_subquery (Query *q, const constants_t *constants)
 Push IS [NOT] NULL on a subquery's aggregate down into that subquery's HAVING.
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 bool sortgroupref_is_key (Query *q, Index ref)
 Whether ref is a GROUP BY or DISTINCT key of q.
static bool aggref_values_explodable (const constants_t *constants, Aggref *a)
 Whether the values the aggregate a takes over the possible worlds can be enumerated, so that it can be exploded into one row per value (agg_possible_values).
static bool setop_column_explodable (const constants_t *constants, Query *q, Node *n, AttrNumber attno)
 Whether column attno of every arm of the set-operation tree n of q is an aggregate that can be exploded.
static bool setop_column_has_aggregate (const constants_t *constants, Query *q, Node *n, AttrNumber attno)
 Whether column attno of some arm of the set-operation tree n of q is an aggregate result.
static bool reads_subquery_aggregate_walker (Node *node, void *cx)
 Walker: a Var of this level reading a column that is an aggregate of a FROM subquery.
static void refuse_agg_token_group_key (const constants_t *constants, Query *q)
 Refuse a GROUP BY / DISTINCT key that is an expression over the value of a subquery's aggregate.
static List * agg_values_read_as_data (const constants_t *constants, Query *q, Index *rteid)
 Every aggregate column of ONE subquery that q reads as data, as a list of explode_col, or NIL.
static bool agg_cmp_against_constant (Node *n, Aggref **agg_out, bool *nullable)
 Is n a comparison of an aggregate of this level against a constant, of a shape the explosion can annotate?
static bool unplain_agg_walker (Node *n, const constants_t *constants)
 Find the first comparison of an aggregate against a constant.
static bool agg_cmp_truth_walker (Node *n, agg_cmp_truth_ctx *ctx)
static Node * agg_cmp_subst_mutator (Node *n, void *context)
static Query * rewrite_explode_scalar_agg_cmp_truth (Query *q, const constants_t *constants)
 Explode the truth of a comparison of an aggregate against a constant, read in the select list of a SCALAR aggregation, into one row per truth.
static Node * explode_value_of_text (Node *txt, Oid value_type)
 The text of an exploded value cast to the type of the aggregate.
static bool explode_setop_arms (Query *q, const constants_t *constants, Node *n, List *cols)
 Explode column attno of every arm of the set-operation tree n of q.
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 bool rows_are_products_of_distinct_inputs (const Query *q, List **relids)
 Build the inversion-free marker context for top-level query q.
static InvFreeMarkerCtx * build_inversion_free_ctx (const constants_t *constants, Query *q, char **cert_out)
static List * inv_free_arm_head_vars (Query *arm)
 The output (head) columns of a UNION arm as plain base Var\ s.
static OpExpr * inv_free_make_eq (Var *v1, Var *v2)
 Build the equality qual v1 = v2, or NULL if the types have no = operator.
static InvFreeMarkerCtx * build_inversion_free_union_ctx (const constants_t *constants, Query *q, char **cert_out)
 Build the inversion-free marker context for a set-semantics UNION of inversion-free branches (the full Jha & Suciu UCQ(OBDD) case).
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 bool join_wholerow_walker (Node *node, void *cx)
 Walker: does any Var reference a dissolved join RTE as a whole row (varattno <= 0)?
static Node * join_alias_resolve_mut (Node *node, void *cx)
 Mutator: replace every Var referencing a dissolved join RTE by its joinaliasvars expression – resolved recursively, since chained joins alias through each other – adjusted to the Var's level.
static bool inner_join_collect (Node *jt, List **refs, List **quals, Bitmapset **joins)
 Recursively collect an all-inner join tree's leaf RangeTblRefs, ON quals, and dissolved RTE_JOIN rtindexes.
static Node * renumber_rte_mut (Node *node, void *cx)
 Mutator: renumber every Var / RangeTblRef / JoinExpr rtindex of the compacted level through old_to_new, at any nesting depth (a nested subquery reaches the level via varlevelsup).
static void normalize_inner_joins (Query *q)
 Canonicalise explicit inner joins in q's FROM to the comma-join form: each all-inner JoinExpr fromlist item becomes its leaf RangeTblRefs, the ON conditions are splayed into one flat WHERE conjunction, every reference to the dissolved joins' alias columns (USING / NATURAL merged columns included) is resolved to base expressions, and the dissolved RTE_JOIN entries are dropped from the range table with every surviving rtindex renumbered.
static bool is_actual_marker (const constants_t *constants, Node *n)
 Whether n is a call of the marker plain(), up to coercions.
static bool limit_truncates (const Query *q)
 Whether the LIMIT / OFFSET of q removes rows.
static bool uncertain_value_walker (Node *node, void *cx)
 Walker: whether an expression of ctx->q may have different values in different possible worlds – an aggregate, a window function, a provenance, a random variable, or a subquery column computed so.
static bool reads_provenance_walker (Node *node, void *cx)
 Walker: whether an expression calls provenance().
static bool is_const_or_param (Node *n)
 Whether n is a constant or a parameter, up to coercions.
static bool sort_key_reads_agg_value (const constants_t *constants, Query *q)
 Whether the LIMIT / OFFSET of q, a query over tracked relations, is rewritten into the filter of a rank (lower_limit_to_rank).
static bool te_reads_agg_value (const constants_t *constants, Query *q, TargetEntry *te)
 Whether the entry te of q reads the value of an aggregate.
static bool limit_lowerable (const constants_t *constants, Query *q)
static bool conjunct_tests_tracked_sublink (const constants_t *constants, Node *n)
 Whether n, a conjunct of a WHERE, tests a subquery over a tracked relation.
static bool count_agg_body_sublinks_walker (Node *node, void *cx)
 Walker: count the scalar subquery expressions with an aggregate body in node (not in their bodies).
static int count_agg_body_sublinks (Node *node)
 The number of scalar subquery expressions with an aggregate body in node.
static bool outer_refs_are_keys_walker (Node *node, void *cx)
 Walker: every Var of the query depth levels up is one of its grouping expressions, and no aggregate of that query is read.
static bool expose_outer_refs_walker (Node *node, void *cx)
 Walker: expose in ctx->base.inner the Vars of its level that the subquery expressions in node read (ctx->depth levels up from where the walk is).
static Node * targetlist_sublink_mutator (Node *node, void *cx)
 Mutator: the subquery expressions to compute in the subquery become references to its columns; the Vars of the query, in the target list and in the subqueries left, references to the columns exposing them.
static Query * split_targetlist_sublinks (const constants_t *constants, Query *q)
 Compute the subquery expressions of a target list in a subquery.
static Query * split_predicate_sublinks (const constants_t *constants, Query *q)
 Test the subqueries of a WHERE one after the other: move all but the first into an enclosing query.
static Query * split_aggregation_over_sublinks (const constants_t *constants, Query *q)
 Move the join and the WHERE of an aggregation or a DISTINCT whose WHERE tests subqueries into a subquery of its own.
static Query * distinct_over_windows (const constants_t *constants, Query *q)
 Move the window values of a SELECT DISTINCT into a subquery.
static bool is_movable_uncorrelated_sublink (const constants_t *constants, TargetEntry *te, List *ctes)
 Is te a scalar subquery that move_uncorrelated_sublinks_to_from moves to the FROM?
static Query * scalar_agg_over_uncorrelated_sublinks (const constants_t *constants, Query *q)
 Move an aggregation without GROUP BY into a subquery, leaving out its uncorrelated scalar subqueries.
static Query * lower_to_rank_filter (const constants_t *constants, Query *q, List *partition, List *order, Node *count, Node *offset, bool ties, List *outer_sort)
 The core of lower_limit_to_rank and lower_distinct_on_to_rank: keep the rows of q whose rank, in the window of partition partition and order order, is above offset and at most offset + count (either may be NULL); rank() if ties, row_number() otherwise.
static Query * lower_limit_to_rank (const constants_t *constants, Query *q)
 Rewrite the LIMIT / OFFSET of q into the filter of a rank, or return NULL if it is not (limit_lowerable).
static Query * lower_distinct_on_to_rank (const constants_t *constants, Query *q)
 Rewrite the DISTINCT ON of q into the filter of a rank, or return NULL if it is not.
static bool is_provsql_column (const constants_t *constants, Query *q, Node *n)
 Whether n is a column named provsql of type uuid of an entry of q's range table.
static Node * strip_provsql_equalities (const constants_t *constants, Query *q, Node *quals)
 quals without the equalities between two provsql columns.
static void strip_provsql_join_quals (const constants_t *constants, Query *q, Node *jt)
 Remove the provsql columns from the join conditions of the NATURAL and USING joins of jt (see strip_provsql_join_columns).
static bool strip_provsql_join_columns (Node *node, void *cx)
 Walker: a NATURAL join of two tracked relations, or a join USING their provsql column, does not join on it.
static bool normalize_inner_joins_walker (Node *node, void *cx)
 Walker: apply normalize_inner_joins to every nested Query – sublink subselects, subquery RTEs, CTE bodies – so that e.g.
static bool has_outer_join_walker (Node *node, void *data)
 Walker: an outer join in a join tree.
static Var * tracked_wholerow (wholerow_ctx *ctx, Node *n)
 The whole-row Var n of a provenance-tracked relation, or of a subquery the rewriting tracks (a view, a derived table), of the range table of the query of ctx, or NULL.
static Node * row_without_provsql (wholerow_ctx *ctx, Var *v)
 The row of the columns of v's relation or subquery other than provsql, as an anonymous record; NULL where the whole row is (the null-padded side of an outer join).
static bool param_takes_any_row (Oid funcid, int i)
 Whether argument i of funcid takes any row: a parameter of type record, "any", or a polymorphic one of a function whose result type does not follow it (row_to_json, to_jsonb, json_agg...).
static Node * wholerow_mutator (Node *node, void *cx)
 Mutator: replace the whole-row values of tracked relations read as any row (see hide_provsql_in_wholerows).
static bool sort_key_reads_agg_null_walker (Node *node, void *cx)
 Walker: does the expression hold an IS [NOT] NULL of an aggregate result?
static void refuse_tracked_group_key (const constants_t *constants, Query *q)
 Refuse a grouping key that is STILL an agg_token once every rewriting has run.
static void sort_on_plain_values (const constants_t *constants, Query *q, bool top_level)
 Sort an ORDER BY on an aggregate result on its value.
static Node * pull_aggregates_mutator (Node *node, void *cx)
 Mutator: an aggregate or a column of this level becomes a reference to the column of ctx->inner exposing it.
static bool window_reads_aggregate (Query *q)
 Whether a window of q reads an aggregate of q itself.
static Index partition_only_winref (Query *q, WindowClause *wc)
 The window with the partition of wc and no ordering, creating it where the query has none: what cume_dist divides by.
static WindowFunc * window_count_star (Index winref)
 count(*) over the window winref.
static Node * cume_dist_mutator (Node *node, void *cx)
 Mutator: each cume_dist() becomes the ratio of counts it is.
static Query * rewrite_cume_dist (const constants_t *constants, Query *q)
 Rewrite the cume_dist() windows of q into ratios of counts, or return NULL leaving q alone.
static Query * split_window_over_aggregates (const constants_t *constants, Query *q)
static Query * split_distinct_over_aggregates (const constants_t *constants, Query *q)
 Compute the aggregation of q in a subquery when a DISTINCT of its own deduplicates its results.
static void rank_key_vars (rank_window_ctx *ctx, SortGroupClause *k, Var **inner, Var **outer)
 The two readings of a sort key of a rank: b.k inside the subquery that counts, and a.k of the row ranked, one level up.
static bool rank_key_is_aggregate (rank_window_ctx *ctx, SortGroupClause *k)
 Whether the key k of a rank reads an aggregate result, which is compared per possible world, rather than a value of the data.
static Node * rank_key_before (rank_window_ctx *ctx, SortGroupClause *k)
 "b.k ≺ a.k" – the row the counting subquery reads comes strictly before the one ranked, on the key k alone.
static Node * rank_key_same (rank_window_ctx *ctx, SortGroupClause *k)
 "b.k = a.k" – the two rows tie on the key k, so the next key decides.
static Expr * make_rank_subquery (rank_window_ctx *ctx, WindowFunc *wf, bool dense)
 The rank of the current row among those of ctx->rtindex, as a subquery counting them, or NULL.
static void add_dense_distinct_col (List **tl, List **dclause, List **colnames, Var *src, const char *name, Index *ref)
 Add a column of src to the DISTINCT list tl of the values subquery of a dense rank.
static Expr * make_dense_rank_subquery (rank_window_ctx *ctx, WindowFunc *wf)
 The dense rank of the current row among those of ctx->rtindex, as a subquery counting the keys up to its own, or NULL.
static bool rank_order_is_total (rank_window_ctx *ctx, WindowFunc *wf)
 Whether the order of the rank window wf tells every two rows of the relation ranked apart, so that no two of them tie.
static Node * replace_rank_window_mutator (Node *node, void *cx)
 Mutator: each rank window over the key of ctx becomes the subquery counting the rows before the current one.
static Query * rewrite_rank_over_aggregate (const constants_t *constants, Query *q)
 Rewrite the ranks of a window ordered by an aggregate result into subqueries counting the rows before each row.
static bool collect_source_var_types (Node *node, void *cx)
 Walker: record the column types the INSERT expects from its source.
static void restore_insert_source_types (Query *q, Index src_rteid, Query *subquery)
 Coerce the rewritten source SELECT back to the types the INSERT expects.
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 bool reads_provsql_walker (Node *node, void *cx)
 Walker: does any expression read a provsql column?
static bool sublink_body_reads_provsql (Node *node, void *cx)
 Walker: does a sublink of this level have a body that READS the provenance column?
static Query * lift_tracked_sublinks (const constants_t *constants, Query *q)
 Lift the tracked bodies of a block's sublinks into its FROM.
static bool nested_limit_on_provenance (const constants_t *constants, Query *q, bool top)
 Whether a LIMIT / OFFSET that stays a truncation applies to a provenance-tracked query below the top level of q.
static bool set_operation_has_except_all (Node *node)
 Whether a set-operation tree contains an EXCEPT ALL node.
static bool except_all_on_provenance_walker (Node *node, void *data)
 Walker: is there, anywhere in the statement as the user wrote it, an EXCEPT ALL over provenance-tracked relations?
static void refuse_except_all (const constants_t *constants, Query *q)
 Raise the error except_all_on_provenance_walker calls for.
static bool top_limit_is_truncation (const constants_t *constants, Query *q)
 Whether the ORDER BY ... LIMIT / OFFSET of q, the top level of a statement over tracked relations, stays a truncation of the actual result without being marked so.
static bool reads_agg_value_walker (Node *node, void *cx)
 Walker: does the expression read the value of an aggregate?
static void warn_top_limit (const constants_t *constants, Query *q)
 Report the freezing top_limit_is_truncation calls for.
static void warn_nested_limit (const constants_t *constants)
 Report the freezing nested_limit_on_provenance calls for.
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)
 Replace the ancestor half of a relation's row, keeping its kind / block_key.
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)
static bool colref_is_star (const char *src, int loc)
 Whether the column reference written at loc of src is a star (*, t.
static int sortby_position (Node *n)
 The integer of a positional ORDER BY item, or 0.
static List * statement_sort_items (Query *q, const char *src)
 The ORDER BY items of the statement q was analysed from, re-read from its text, or NIL.
static void remap_positional_sort (Query *q, const char *src, List *resolved, List *shown)
 Point the positional ORDER BY keys of q at the columns in the order the result shows them.
static bool var_of_relation (Query *q, Var *v)
 Whether v is a column of a table or view of q, directly or through joins (before PostgreSQL 13, * over a join expands to Vars of the join RTE).
static void place_star_provsql_last (Query *q, const char *src)
 Put the provsql column that * expands to at the end of the target list of q, as the rewriting shows it.
static Node * rowstar_mutator (Node *node, void *cx)
 Mutator: leave the provsql column that * expands to out of the anonymous rows ROW(t.
static void provsql_post_parse_analyze (ParseState *pstate, Query *query)
 Post-parse-analysis hook: see place_star_provsql_last.

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.
int provsql_implicit_freeze = PROVSQL_FREEZE_WARN
 What an implicit freezing does: warn, or error; provsql.implicit_freeze GUC.
char * provsql_last_eval_method = NULL
 Last probability evaluation method(s) used; exposed via provsql.last_eval_method.
char * provsql_transaction_token = NULL
 Textual UUID of the update gate standing for the current transaction, or empty; set with SET LOCAL by provsql.transaction_token().
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.
double provsql_ess_warn_fraction = 0.1
 Effective-sample-size warning threshold for likelihood weighting: warn when the posterior ESS falls below this fraction of the accepted draws; controlled by the provsql.ess_warn_fraction 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_gate_cache_size = 65536
 Byte budget, in kB, of the per-backend gate cache; provsql.gate_cache_size 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.
int provsql_mobius_max_cnf = 8
 Query-cost cap of the Möbius route: it declines when a sentence's CNF has more than this many conjuncts, since the inclusion-exclusion lattice it walks has \(2^M\) elements; ranking / shattering can inflate the conjunct count, which is what raising it buys; provsql.mobius_max_cnf 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 int provsql_in_ctas = 0
 Depth of CREATE TABLE AS / SELECT INTO / CREATE MATERIALIZED VIEW being executed: their query's output is stored, not shown.
static int provsql_executor_depth = 0
 Executor nesting depth.
unsigned provsql_stmt_serial = 0
 Counts the user's statements, so that a warning a conversion emits at run time is given once for a statement rather than once per row.
static int provsql_subxact_depth [PROVSQL_MAX_SUBXACT_DEPTH]
static bool agg_over_agg_frozen = false
 An aggregate of the statement being planned reads the value of another as a plain value, the pair not being one the reaggregation carries (an avg of a count, a max of a sum).
static post_parse_analyze_hook_type prev_post_parse_analyze = NULL
 Previous post-parse-analysis hook (chained).
static const char *const null_iff_no_value []
 The aggregates that are NULL exactly when they read no value: their NULL-ness is the presence of a value row.
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 SubLink * last_tracked_sublink = NULL
 The last subquery expression tracked_value_sublink_walker found reading tracked data.
static Query * freeze_statement = NULL
 The statement being rewritten, whose relations a frozen part is compared with (report_freeze).
static bool nested_sublink_warned = false
 Set when process_query warns of a nested scalar subquery, so that provsql_planner does not warn of it again.
static ExecutorStart_hook_type prev_ExecutorStart = NULL
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL
static ProcessUtility_hook_type prev_ProcessUtility = NULL

Detailed Description

PostgreSQL planner hook for transparent provenance tracking.

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

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

Definition in file provsql.c.

Macro Definition Documentation

◆ INT_ZERO

#define INT_ZERO ( )
Value:
((Node *)makeConst(INT4OID, -1, InvalidOid, sizeof(int32), \
Int32GetDatum(0), false, true))

◆ POSSIBLE_HI

#define POSSIBLE_HI ( bound)
Value:
((Expr *)build_binop(strict ? ">" : ">=", (Node *)(bound), copyObject(c)))
static Node * build_binop(const char *op, Node *l, Node *r)
Build l <op> r, resolving the operator by name.
Definition provsql.c:4800

◆ POSSIBLE_LO

#define POSSIBLE_LO ( bound)
Value:
((Expr *)build_binop(strict ? "<" : "<=", (Node *)(bound), copyObject(c)))

◆ PROVSQL_AGG_COUNT_COLNAME

#define PROVSQL_AGG_COUNT_COLNAME   "provsql_agg_count"

Column of the companion count that gates the NULL value of an exploded aggregate (rewrite_explode_agg_value).

Definition at line 200 of file provsql.c.

◆ PROVSQL_DENSE_ALIAS

#define PROVSQL_DENSE_ALIAS   "provsql_dense_keys"

Alias of the deduplicated keys a dense rank counts (make_dense_rank_subquery).

Definition at line 204 of file provsql.c.

◆ PROVSQL_DISTINCT_ALIAS

#define PROVSQL_DISTINCT_ALIAS   "provsql_distinct"

Alias prefix of the subqueries rewrite_agg_distinct joins, one per AGG(DISTINCT x).

Their rows are the groups of the query, and the provenance of a group holds whenever one of its rows does: multiplying it into each row's token would change nothing (δ-absorption) but would make the rows of a group share a token, which the evaluators of an aggregate over independent rows (the exact AVG, ...) take as a correlation. get_provenance_attributes leaves it out.

Definition at line 183 of file provsql.c.

◆ PROVSQL_EXPLODE_ALIAS

#define PROVSQL_EXPLODE_ALIAS   "provsql_agg_value"

Alias of the lateral column an aggregate value is exploded into: one row per value the aggregate takes over the possible worlds (rewrite_explode_agg_value).

Definition at line 188 of file provsql.c.

◆ PROVSQL_FLATTEN

#define PROVSQL_FLATTEN ( n)
Value:
flatten_join_alias_vars(&root, (n))

◆ PROVSQL_INERT_QUERY_ID

#define PROVSQL_INERT_QUERY_ID   0x70727673 /* "prvs", fits every queryId type */

The queryId marking an inert provenance()-fetch subselect (and its copies).

PostgreSQL sets queryId only on the query of a statement, not on those of its sublinks.

Definition at line 12551 of file provsql.c.

◆ PROVSQL_JOIN_ALIAS

#define PROVSQL_JOIN_ALIAS   "provsql_join"

Sentinel eref alias marking join RTEs that ProvSQL itself constructs (the EXCEPT antijoin, the sublink decorrelation): their monus construction accounts for the null-padded rows, so check_unlowered_outer_joins skips them.

Definition at line 12937 of file provsql.c.

◆ PROVSQL_MATCH_IND_COLNAME

#define PROVSQL_MATCH_IND_COLNAME   "provsql_match_ind"

Column name of the constant match indicator added by oj_wrap_body_with_match_ind.

Definition at line 18442 of file provsql.c.

◆ PROVSQL_MAX_SUBXACT_DEPTH

#define PROVSQL_MAX_SUBXACT_DEPTH   64

provsql_executor_depth when each open subtransaction started, by nesting level, to restore it when the subtransaction aborts.

Definition at line 228 of file provsql.c.

◆ PROVSQL_REC_PREFIX

#define PROVSQL_REC_PREFIX   "provsql_rec_"

Prefix of the temporary tables the recursion lowering fills (rec_work_table_name).

Definition at line 197 of file provsql.c.

◆ PROVSQL_STAR_COLUMN_NAME

#define PROVSQL_STAR_COLUMN_NAME   "provsql_star"

Name the recursion lowering gives, in the rounds, to the provenance column a "SELECT *" put in a recursive CTE (neutralise_star_provenance).

Definition at line 194 of file provsql.c.

◆ PROVSQL_TRUTH_ALIAS

#define PROVSQL_TRUTH_ALIAS   "provsql_agg_truth"

Alias of the two-row source the truth of a comparison of an aggregate explodes over (rewrite_explode_agg_cmp_truth).

Definition at line 191 of file provsql.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Values of provsql.implicit_freeze.

Enumerator
PROVSQL_FREEZE_WARN 
PROVSQL_FREEZE_ERROR 

Definition at line 115 of file provsql.c.

◆ provsql_provenance_class_t

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

Enumerator
PROVSQL_PROVENANCE_WHERE 

Universal semiring provenance plus where-provenance gates.

PROVSQL_PROVENANCE_SEMIRING 

Universal semiring provenance (default).

PROVSQL_PROVENANCE_ABSORPTIVE 

Absorptive-semiring constructions licensed (tagged).

PROVSQL_PROVENANCE_BOOLEAN 

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

Definition at line 142 of file provsql.c.

◆ qual_class

enum qual_class

Categorisation of a top-level WHERE conjunct.

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

Enumerator
QUAL_DETERMINISTIC 

no probabilistic value; stays in WHERE

QUAL_PURE_AGG 

pure agg_token expression; route to HAVING

QUAL_PURE_RV 

pure random_variable expression; lift to provenance

QUAL_MIXED_AGG_DET 

agg_token mixed with non-agg leaves; error

QUAL_MIXED_RV_DET 

random_variable mixed with non-RV leaves; error

QUAL_MIXED_AGG_RV 

agg_token and random_variable in the same expr; error

Definition at line 20914 of file provsql.c.

◆ semiring_operation

Semiring operation used to combine provenance tokens.

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

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

Semiring addition (UNION, SELECT DISTINCT).

SR_MONUS 

Semiring monus / set difference (EXCEPT).

SR_TIMES 

Semiring multiplication (JOIN, Cartesian product).

Definition at line 3767 of file provsql.c.

Function Documentation

◆ _PG_fini()

void _PG_fini ( void )
extern

Extension teardown – restores the planner and shmem hooks.

Definition at line 31131 of file provsql.c.

Here is the call graph for this function:

◆ _PG_init()

void _PG_init ( void )
extern

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

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

Must be loaded via shared_preload_libraries; raises an error otherwise.

Definition at line 30485 of file provsql.c.

Here is the call graph for this function:

◆ add_dense_distinct_col()

void add_dense_distinct_col ( List ** tl,
List ** dclause,
List ** colnames,
Var * src,
const char * name,
Index * ref )
static

Add a column of src to the DISTINCT list tl of the values subquery of a dense rank.

Definition at line 27384 of file provsql.c.

Here is the caller graph for this function:

◆ add_eq_from_OpExpr_to_Expr()

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

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

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

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

Definition at line 3800 of file provsql.c.

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

◆ add_eq_from_Quals_to_Expr()

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

add_eq_from_Quals_to_Expr_cond for quals that always apply.

Definition at line 3940 of file provsql.c.

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

◆ add_eq_from_Quals_to_Expr_cond()

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

Walk a join-condition or WHERE quals node and add eq gates for the column equalities that make the row an answer.

An equality A = B of a selection lets the value of either column have been copied from the other (Buneman, Khanna & Tan): an eq gate merges the where-provenance of the two positions. Over a Boolean combination this follows the reading of a disjunction as a union, whose where-provenance is the union of those of its arms: a row gets the equalities of the disjuncts it satisfies. Which ones it does is known when the row is built, so an equality reached under a condition cond contributes "CASE WHEN cond THEN provenance_eq(token, i, j) ELSE token END". Under an AND the children inherit cond; under an OR the child φ gets "cond AND (φ IS TRUE)"; a NOT contributes nothing, a negated equality copying no value.

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

Definition at line 3886 of file provsql.c.

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

◆ add_select_non_zero()

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

Add a WHERE condition filtering out zero-provenance tuples.

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

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

Definition at line 20680 of file provsql.c.

Here is the caller graph for this function:

◆ add_to_havingQual()

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

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

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

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

Definition at line 20717 of file provsql.c.

Here is the caller graph for this function:

◆ add_to_select()

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

Append the provenance expression to q's target list.

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

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

Definition at line 11411 of file provsql.c.

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

◆ agg_arith_numeric_operand()

Node * agg_arith_numeric_operand ( Node * n)
static

The operand an agg_token operator can be given, as numeric.

The agg_token arithmetic operators take their other operand as numeric, which every integer type reaches by an implicit cast. A floating-point one does not: real and double precision only reach numeric by an assignment cast, so resolution would rather cast BOTH operands to random_variable – a type both reach implicitly, whose operators carry no aggregate – and the swap would then be declined. The cast is written here instead, the gate computing in numeric anyway.

Definition at line 10254 of file provsql.c.

Here is the caller graph for this function:

◆ agg_arith_strict_null_gate()

FuncExpr * agg_arith_strict_null_gate ( List * args,
List * div_args,
const constants_t * constants,
bool want_null )
static

The gate of "expr IS [NOT] NULL" for an arithmetic expression over agg_token, strict in every operand of args.

div_args, when not NIL, says the arithmetic is a DIVISION and carries its two arguments: its second is the divisor, whose reading zero makes the division null on top of any operand's own nullness (divisor_zero_gate).

Definition at line 5622 of file provsql.c.

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

◆ agg_arm_to_uuid()

Node * agg_arm_to_uuid ( Node * arm,
const constants_t * constants )
static

Definition at line 7253 of file provsql.c.

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

◆ agg_arm_to_uuid_or_null()

Node * agg_arm_to_uuid_or_null ( Node * arm,
const constants_t * constants )
static

Definition at line 7272 of file provsql.c.

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

◆ agg_cmp_against_constant()

bool agg_cmp_against_constant ( Node * n,
Aggref ** agg_out,
bool * nullable )
static

Is n a comparison of an aggregate of this level against a constant, of a shape the explosion can annotate?

The aggregate side must be a bare aggregate call, and one whose NULL-ness the explosion can express: count never is NULL, and sum / avg / min / max / choose are exactly when they read no value, which having_NullTest_to_provenance annotates. Anything else – arithmetic over aggregates, an aggregate that is NULL over a single value (stddev), two aggregates compared with each other – would leave the worlds where the comparison is unknown out of both truths, and those rows would silently vanish, so it is declined and the value stays frozen.

Parameters
nNode to test.
agg_outOut (optional): the aggregate call.
nullableOut (optional): whether that aggregate can be NULL over a group that exists, so that the explosion needs its third, unknown row.

Definition at line 22768 of file provsql.c.

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

◆ agg_cmp_subst_mutator()

Node * agg_cmp_subst_mutator ( Node * n,
void * context )
static

Definition at line 22900 of file provsql.c.

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

◆ agg_cmp_truth_walker()

bool agg_cmp_truth_walker ( Node * n,
agg_cmp_truth_ctx * ctx )
static

Definition at line 22851 of file provsql.c.

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

◆ agg_column_explodable()

bool agg_column_explodable ( const constants_t * constants,
RangeTblEntry * rte,
AttrNumber attno )
static

Whether column attno of the subquery rte is the result of an aggregate that can be exploded into one row per value it takes.

The aggregate is not always computed by the subquery itself: a level that only forwards the column stands between them whenever a rewriting has moved the aggregation (the deduplication of a count(DISTINCT), the decorrelation of a subquery that reads it). Such a column is followed down to the aggregate it forwards, the explosion being the same wherever the value is read.

Definition at line 22503 of file provsql.c.

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

◆ agg_distinct_args_supported()

bool agg_distinct_args_supported ( Aggref * ar)
static

Can ar, an AGG(DISTINCT), be computed over the distinct values of its first argument?

Its other arguments must be constants (string_agg(DISTINCT x, ',')), and an ORDER BY inside it must be on the first argument, the only one the subquery of distinct values provides.

Definition at line 9518 of file provsql.c.

Here is the caller graph for this function:

◆ agg_expr_null_gate()

FuncExpr * agg_expr_null_gate ( Node * arg,
const constants_t * constants,
bool want_null )
static

Definition at line 5663 of file provsql.c.

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

◆ agg_func_carried()

bool agg_func_carried ( const char * name)
static

Whether the comparison op of an aggregate with an aggregate-free term may hold in some world; NULL when nothing is known.

With [lo, hi] the range of the aggregate over the non-empty selections of its group's rows, and c the other term: >= is possible iff hi >= c, <= iff lo <= c, = iff both, and strictly so for > and <. The ends are

  • count: hi is the count itself; lo is not used (0 is always sound);
  • sum: hi is the sum of the positive values, or at most 0 without any, and symmetrically for lo; the group must have a non-NULL value at all;
  • max: hi is the max itself, lo the min of the values; min: the reverse; avg: the min and the max. A NULL end or a NULL c makes the condition NULL, and the group is dropped: the comparison is then unknown in every world.

Whether the possibility condition of a comparison under the SQL function name is one having_possible_carried knows how to relax: floor, ceil and round move a value by less than one, and abs reflects it.

Narrower on purpose than what try_swap_agg_func carries, which is whatever has a provsql counterpart: a relaxation is sound only for the functions it was reasoned about.

Definition at line 6234 of file provsql.c.

Here is the caller graph for this function:

◆ agg_nulltest_target()

TargetEntry * agg_nulltest_target ( Query * q,
NullTest * nt,
const constants_t * constants,
Query ** sub_out )
static

The subquery target entry an IS [NOT] NULL is testing, if it is an aggregate of a subquery in q.

Returns
The subquery's TargetEntry for the tested column, or NULL when nt is not of that shape. Writes the owning subquery to *sub_out on success.

Definition at line 21879 of file provsql.c.

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

◆ agg_token_division_args()

List * agg_token_division_args ( Node * node,
const constants_t * constants )
static

The arguments of a division over agg_token, or NIL.

Both spellings the rewriting makes: the "/" operator over agg_token, and the agg_token_intdiv counterpart a division the query wrote on integers is routed to, which is a call and not an operator.

Definition at line 5589 of file provsql.c.

Here is the caller graph for this function:

◆ agg_token_null_test_walker()

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

Walker: a NULL test left ON an agg_token, which reads the aggregate's nullness in the database as it is.

The truth of IS NULL over a tracked aggregate is exploded into the truths the worlds give it (rewrite_explode_agg_cmp_truth where the block groups, rewrite_explode_scalar_agg_cmp_truth where it does not). A block those decline – one with a window function – leaves the test on the token, and it answers, since provenance_aggregate returns SQL NULL exactly where the aggregate has no value in the data as it is. That is the right answer for that one world and says nothing about the others, which is what every other plain reading of an aggregate is reported for; the comparison in the same position is reported already, through the frozen_agg_value it goes through, and the null test goes through none.

A test that is only a SORT KEY is passed over: sort_on_plain_values says of it that the order reads the plain value, and one reading wants one report. A test a query both answers and orders by is an answer, its target entry carrying the value out, and is reported.

Definition at line 13815 of file provsql.c.

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

◆ agg_token_var_of_stored_relation()

bool agg_token_var_of_stored_relation ( Var * v,
insert_agg_token_casts_context * ctx )
static

Whether v reads an agg_token column of a stored relation, rather than one this statement computes (a subquery's aggregate).

Definition at line 21213 of file provsql.c.

Here is the caller graph for this function:

◆ agg_token_var_walker()

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

expression_tree_walker predicate: some Var below node has type agg_token.

Definition at line 755 of file provsql.c.

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

◆ agg_values_read_as_data()

List * agg_values_read_as_data ( const constants_t * constants,
Query * q,
Index * rteid )
static

Every aggregate column of ONE subquery that q reads as data, as a list of explode_col, or NIL.

agg_value_read_as_data answers with the first such column; the explosion takes all of a subquery's at once, each column's NULL value being read off its own Aggref (see rewrite_explode_agg_values). Columns of a second subquery are left to the next pass, which recursion reaches.

Definition at line 22652 of file provsql.c.

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

◆ aggref_over_agg_token_walker()

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

expression_tree_walker noting an Aggref whose arguments read an agg_token column: an aggregate of an aggregate result from a subquery (max of a count, avg of a sum...) that is no pair the reaggregation carries (reaggregates_agg_result) reads the inner value as a plain value, reported once per statement, rather than refusing the statement.

Definition at line 913 of file provsql.c.

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

◆ aggref_over_all_rows()

Aggref * aggref_over_all_rows ( Aggref * ar,
const constants_t * constants )
static

The original Aggref behind the aggregate side of a comparison, or NULL if node is not a lowered aggregate of this query level.

Copy of the displayed aggregate ar without the plain_truth filter make_aggregation_expression may have added: over every row a world may contain, not only those of the database as it is.

Definition at line 5955 of file provsql.c.

Here is the caller graph for this function:

◆ aggref_sibling()

Aggref * aggref_sibling ( Aggref * ar,
const char * name )
static

Copy of ar computing the built-in aggregate name ("min" or "max") of the same argument, or NULL if there is none declared on exactly that argument type.

Definition at line 6179 of file provsql.c.

Here is the caller graph for this function:

◆ aggref_values_explodable()

bool aggref_values_explodable ( const constants_t * constants,
Aggref * a )
static

Whether the values the aggregate a takes over the possible worlds can be enumerated, so that it can be exploded into one row per value (agg_possible_values).

A count() takes every number of the rows it counts, a min(), a max() and a choose() one of the values they aggregate, and a sum() over an integer column one of its subset sums.

A sum() over any other column is left out, and with it avg(): the value of a summation is read back through the evaluator's own arithmetic, which is that of a double, and a subset sum of numbers that are not integers is not the number that arithmetic reaches (0.1 + 0.2 comparing unequal to 0.3 would lose the row rather than report anything). A string_agg() takes one value per ordering. All of those are left to the freezing of their value.

Definition at line 22433 of file provsql.c.

Here is the caller graph for this function:

◆ aggref_with_filter()

Aggref * aggref_with_filter ( Aggref * ar,
Expr * cond )
static

Copy of ar with cond ANDed to its FILTER clause.

Definition at line 5986 of file provsql.c.

Here is the caller graph for this function:

◆ aggregate_keeps_nulls()

bool aggregate_keeps_nulls ( const constants_t * constants,
Oid aggfnoid )
static

Whether a NULL input is part of what aggregate aggfnoid sees.

SQL aggregates ignore NULL inputs, with a few built-in exceptions whose result lists every input, NULLs included: array_agg, json_agg, jsonb_agg, json_object_agg, jsonb_object_agg. For built-in aggregates the catalog cannot tell the two kinds apart (a non-strict transition function says nothing: sum(bigint) and string_agg have one and skip NULLs), hence the explicit list.

For a user-defined aggregate the transition function is all there is to go by. A strict one is never called on a NULL input, so the aggregate skips NULLs. A non-strict one does receive them; what it makes of them is unknown, and the row is kept, which loses nothing: a kept NULL input can still be ignored downstream, a dropped one cannot be recovered. ProvSQL's own choose is non-strict and skips NULLs.

Definition at line 4273 of file provsql.c.

Here is the caller graph for this function:

◆ aggregate_null_has_reading()

bool aggregate_null_has_reading ( Oid aggfnoid,
const constants_t * constants )
static

Whether the NULL-ness of an aggregate of this kind has a reading at all: what having_NullTest_to_provenance builds a gate for, and what the guards of a lowered CASE may therefore ask.

Definition at line 5203 of file provsql.c.

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

◆ aggregation_mutator()

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

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

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

Definition at line 9989 of file provsql.c.

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

◆ aggregation_type_mutator()

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

Tree-mutator that retypes a specific Var to agg_token.

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

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

Definition at line 617 of file provsql.c.

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

◆ aggtoken_walker()

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

Tree walker that detects any Var of type agg_token.

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

Definition at line 14081 of file provsql.c.

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

◆ body_reads_tracked_cte()

bool body_reads_tracked_cte ( const constants_t * constants,
List * ctes,
Query * body )
static

Whether body reads a WITH entry of ctes that is tracked.

A sublink body that reads a CTE has an RTE_CTE, not a relation, so has_provenance of the body alone says nothing: what is tracked is the CTE's own query, declared at the level the sublink sits in.

Definition at line 12817 of file provsql.c.

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

◆ bool_agg_to_int_case()

Node * bool_agg_to_int_case ( Node * agg,
const constants_t * constants )
static

A Boolean aggregate cast to an integer, as the searched CASE that cast means.

The only cast SQL has on a Boolean is to an integer type, and it answers 1 for true, 0 for false and NULL for NULL. The value of a Boolean aggregate is no number, so the carried counterparts, which compute in numeric, cannot take it – but the indicator the cast stands for is a CASE they can:

CASE WHEN agg = true THEN 1 WHEN agg = false THEN 0 ELSE NULL END

whose guards are the equality the boolean-domain evaluator resolves – the one "HAVING bool_or(x)" is normalised to – and whose arms are constants, lifted into value gates. Two comparisons rather than a NULL test and one: a NULL aggregate makes both of them unknown, so the default answers for it, which is what the cast does, and the two guards are then shapes the gate's own value reads as well as the evaluators do (the IS NULL of a grouped aggregate is a product with a monus, which it does not). What comes out is an agg_token like any other carried cast, so "bool_or(flag)::int" is read in every world instead of frozen.

Declines where the NULL-ness of agg has no reading (an agg_token read through a subquery exposes no aggregate), and the cast is then the reading of the plain value it was.

Definition at line 7488 of file provsql.c.

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

◆ bool_exists_mutator()

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

Rewrite the EXISTS of a Boolean combination into the count of its body.

A subquery condition that is not a conjunct of the WHERE clause – "ψ @c OR @c EXISTS @c (Q)" – is not the semijoin: the semijoin drops the rows of R without a match, which the other disjunct may license. The semantics reads it as the atom "#(k+1) @c >= @c 1" over G_c(R,Q), i.e. the count of the body as a column of its own, combined with the other conditions by the rules of HAVING. Writing the count comparison in place of the EXISTS gives exactly that: decorrelate_scalar_sublinks lifts the aggregate over "R @c ⟕ @c Q" and moves the whole conjunct that holds it – the disjunction – into the HAVING clause, where having_Expr_to_provenance_cmp reads the combination, a regular disjunct becoming its indicator. The annotation is then "α⊗(ψ̂ @c ⊕ @c δ(⊕β))".

One condition per combination: two would need the counts of both bodies on one tuple, which the grouping of one G does not carry into the other, and the decorrelation takes one sublink per level anyway.

Definition at line 17553 of file provsql.c.

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

◆ build_agg_case()

Node * build_agg_case ( CaseExpr * ce,
const constants_t * constants )
static

Definition at line 7354 of file provsql.c.

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

◆ build_binop()

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

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

Definition at line 4800 of file provsql.c.

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

◆ build_column_map()

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

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

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

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

Definition at line 20862 of file provsql.c.

Here is the caller graph for this function:

◆ build_count_predicate()

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

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

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

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

Definition at line 16990 of file provsql.c.

Here is the caller graph for this function:

◆ build_inner_for_distinct_key()

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

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

Produces:

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

Definition at line 9156 of file provsql.c.

Here is the caller graph for this function:

◆ build_inversion_free_ctx()

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

Definition at line 24207 of file provsql.c.

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

◆ build_inversion_free_marker()

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

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

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

Definition at line 23759 of file provsql.c.

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

◆ build_inversion_free_union_ctx()

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

Build the inversion-free marker context for a set-semantics UNION of inversion-free branches (the full Jha & Suciu UCQ(OBDD) case).

A deduplicating UNION is lowered by rewrite_non_all_into_external_group_by to an outer GROUP BY over an inner UNION ALL subquery, whose per-group provenance root is provenance_plus(array_agg(...)) – the OR of the contributing branch tokens (a user GROUP BY over a UNION ALL derived table has the same shape).

Inversion-freeness of a UNION is a joint property of the whole UCQ (a relation shared between two branches can introduce a cross-branch inversion), so a per-arm analysis does not suffice. This builds one synthetic SPJ query merging every arm's base atoms into a single range table (arm variables offset into one numbering, the arms' head columns equated, each arm's WHERE pulled up) and runs the existing detector on it via inversion_free_analyze: shared relations become one relation symbol, so positional consistency and the precedence graph span the whole UCQ, exactly Thm 4.2's condition. The resulting per-atom markers are mapped back to each arm (base relations keep positions 1..n_i since PG 18's synthetic group RTE is appended last and stripped), threaded into the inner arms, and the recipe lands on the outer plus root; the structured d-DNNF then Shannon-decomposes the OR over the joint order (branch-disjoint arms collapse via orDecompose).

Returns NULL – declining to the generic / joint-width / Möbius chain – when q is not a group-over-UNION-ALL of flat inversion-free arms (only the jointly inversion-free class is certified). Sets *cert_out to a serialised recipe (the evaluator routes on its presence; the order comes from the keys).

Definition at line 24377 of file provsql.c.

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

◆ build_joint_width_answer_expr()

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

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

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

Definition at line 8174 of file provsql.c.

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

◆ build_joint_width_provenance_expr()

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

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

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

Definition at line 8092 of file provsql.c.

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

◆ build_mobius_answer_expr()

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

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

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

Definition at line 8244 of file provsql.c.

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

◆ build_mobius_provenance_expr()

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

Build the ucq_mobius_provenance(descriptor, fallback) call.

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

Definition at line 8135 of file provsql.c.

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

◆ build_outer_for_distinct_key()

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

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

Produces:

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

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

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

Definition at line 9232 of file provsql.c.

Here is the caller graph for this function:

◆ build_rv_case()

Node * build_rv_case ( CaseExpr * ce,
const constants_t * constants )
static

Lower an RV-typed searched CASE into a rv_case(...) call.

Flattens "CASE WHEN c_1 THEN v_1 ... ELSE d END" into the wire list [guard_1, value_1, ..., guard_k, value_k, default] and emits rv_case(ARRAY[...]) (a random_variable). Each guard is built with predicate_to_condition_gate (the same lift the WHERE / conditioning surfaces use, so a Boolean combination of RV comparisons – optionally mixed with ordinary comparisons – becomes one event token); each value and the default are relabelled random_variable -> uuid. ce must already have had its sub-expressions mutated (so nested RV CASE values are themselves rv_case calls).

Definition at line 7193 of file provsql.c.

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

◆ build_rv_sum_aggref()

Aggref * build_rv_sum_aggref ( const constants_t * constants,
Oid aggfnoid,
Expr * arg,
Expr * filter )
static

Build an Aggref for an RV-summing aggregate over arg.

Helper for the avg rewrite: the numerator uses rv_sum_or_null (NULL on an empty group) and the denominator uses sum, so the two differ only in aggfnoid. arg is an Expr of type random_variable (the wrapped per-row contribution); filter is the user's FILTER clause, or NULL.

Definition at line 3996 of file provsql.c.

Here is the caller graph for this function:

◆ builtin_aggregate()

Oid builtin_aggregate ( const char * name,
Oid argtype )
static

The built-in aggregate name over argtype, or InvalidOid.

Definition at line 5998 of file provsql.c.

Here is the caller graph for this function:

◆ calls_provenance_walker()

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

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

Definition at line 13238 of file provsql.c.

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

◆ case_has_rv_cmp()

bool case_has_rv_cmp ( CaseExpr * ce,
const constants_t * constants )
static

Does a searched CASE have at least one RV-comparison guard?

The trigger for lowering an RV-typed CASE into a gate_case: a WHEN whose condition carries a random_variable comparison would otherwise raise in random_variable_cmp_placeholder. A CASE over random_variable values with only deterministic guards evaluates fine at runtime and is left alone.

Definition at line 7168 of file provsql.c.

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

◆ case_is_agg_carrier()

bool case_is_agg_carrier ( CaseExpr * ce,
const constants_t * constants )
static

Definition at line 7329 of file provsql.c.

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

◆ case_test_type()

Oid case_test_type ( List * whens)
static

The type of the tested value of a simple CASE, as its WHEN comparisons read it, or InvalidOid.

Definition at line 21316 of file provsql.c.

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

◆ case_test_type_walker()

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

Walker: the type of the first CaseTestExpr below node.

Definition at line 21304 of file provsql.c.

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

◆ cast_agg_token_args()

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

Wrap any agg_token Vars in an argument list.

Definition at line 21289 of file provsql.c.

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

◆ cast_agg_token_func_args()

void cast_agg_token_func_args ( List * args,
Oid funcid,
insert_agg_token_casts_context * ctx )
static

Cast the agg_token arguments of an operator or function that reads values.

An argument whose parameter is agg_token, or a polymorphic parameter of a ProvSQL function (sr_formula(cnt, ...)), keeps its agg_token. Otherwise a subquery's aggregate column is cast to its own type, the one the parser typed the expression with; any other agg_token (the result of arithmetic on one) is cast to the parameter's type, left alone when that is polymorphic.

Definition at line 21351 of file provsql.c.

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

◆ cast_agg_token_in_list()

void cast_agg_token_in_list ( ListCell * lc,
insert_agg_token_casts_context * ctx,
bool through_text,
Oid fallback )
static

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

Definition at line 21227 of file provsql.c.

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

◆ cast_agg_token_mutator()

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

Definition at line 10649 of file provsql.c.

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

◆ cast_agg_token_node()

Node * cast_agg_token_node ( Node * n,
Oid type,
insert_agg_token_casts_context * ctx )
static

Cast one agg_token expression read as a value of type type: a subquery's aggregate column to its own type (else type), any other agg_token to type.

Definition at line 21330 of file provsql.c.

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

◆ cast_agg_token_to_type()

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

Wrap an agg_token expression in a cast to target_type.

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

Definition at line 10029 of file provsql.c.

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

◆ check_boolexpr_on_aggregate()

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

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

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

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

Definition at line 20783 of file provsql.c.

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

◆ check_expr_on_aggregate()

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

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

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

Definition at line 20815 of file provsql.c.

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

◆ check_expr_on_rv()

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

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

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

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

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

Definition at line 7129 of file provsql.c.

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

◆ check_selection_on_aggregate()

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

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

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

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

Definition at line 20750 of file provsql.c.

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

◆ check_unlowered_outer_joins()

void check_unlowered_outer_joins ( const constants_t * constants,
Query * q,
Node * n )
static

Refuse outer joins that survived lower_outer_joins with a provenance-tracked relation on a null-padded side.

The RTE_JOIN arm of get_provenance_attributes treats every join like an inner join: a null-padded row would silently get the ⊗ of the in-scope tokens, although it exists only in the worlds where the tracked padded side has no match. ProvSQL-generated antijoins carry the PROVSQL_JOIN_ALIAS sentinel and are sound (their monus accounts for the padding). A user outer join whose padded side is fully untracked is also sound as-is: its match set is deterministic, so the padded rows correctly keep just the other arm's tokens. Everything else raises, symmetrically with the semi/anti-join refusal.

Definition at line 15276 of file provsql.c.

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

◆ classify_qual()

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

Classify expr along the qual_class axis.

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

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

Definition at line 20940 of file provsql.c.

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

◆ classify_remaining_sublinks()

List * classify_remaining_sublinks ( const constants_t * constants,
Query * q,
bool * has_direct,
SubLink ** offender )
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 13197 of file provsql.c.

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

◆ coalesce_agg_to_case()

CaseExpr * coalesce_agg_to_case ( CoalesceExpr * co,
const constants_t * constants )
static

COALESCE(aggregate, default) as the searched CASE it means.

COALESCE(sum(x), 0) is CASE WHEN sum(x) IS NOT NULL THEN sum(x) ELSE 0 END, and that CASE is one build_agg_case lowers: its guard is a NullTest on an aggregate, which having_Expr_to_provenance_cmp turns into δ(⊕Kn) – a row the aggregate reads a value from is present – and its default is lifted into a value gate. Read as a plain value instead, the whole expression would be frozen, which is what a COALESCE over an aggregate used to be.

Only two arguments, the first a direct aggregate (so the NullTest lowering accepts it rather than raising) and the second a constant: a default that is itself uncertain, or a third argument, is left alone. Returns NULL when the shape does not fit, and the COALESCE stays as the query wrote it.

Definition at line 7416 of file provsql.c.

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

◆ coerce_via_io_to_text()

Expr * coerce_via_io_to_text ( Expr * arg)
static

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

Definition at line 23741 of file provsql.c.

Here is the caller graph for this function:

◆ collect_direct_qual_sublinks()

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

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

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

Definition at line 12901 of file provsql.c.

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

◆ collect_having_distinct_walker()

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

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

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

Definition at line 9342 of file provsql.c.

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

◆ collect_source_var_types()

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

Walker: record the column types the INSERT expects from its source.

Every Var of the INSERT's target list that references the source subquery carries the type parse analysis resolved for that output column, i.e. the type the target column was matched against. Collecting them by attribute number gives restore_insert_source_types the contract the rewritten subquery has to keep.

Definition at line 28643 of file provsql.c.

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

◆ colref_is_star()

bool colref_is_star ( const char * src,
int loc )
static

Whether the column reference written at loc of src is a star (*, t.

*, s.t.*).

Definition at line 30132 of file provsql.c.

Here is the caller graph for this function:

◆ combine_prov_atts()

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

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

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

Returns
An Expr returning UUID; never NULL.

Definition at line 3958 of file provsql.c.

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

◆ combine_safe_routes()

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

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

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

Definition at line 8347 of file provsql.c.

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

◆ cond_predicate_target()

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

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

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

Definition at line 6920 of file provsql.c.

Here is the caller graph for this function:

◆ conjunct_tests_tracked_sublink()

bool conjunct_tests_tracked_sublink ( const constants_t * constants,
Node * n )
static

Whether n, a conjunct of a WHERE, tests a subquery over a tracked relation.

Definition at line 25166 of file provsql.c.

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

◆ const_as_double()

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

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

Definition at line 4752 of file provsql.c.

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

◆ contains_agg_walker()

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

Definition at line 4725 of file provsql.c.

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

◆ contains_aggref_walker()

bool contains_aggref_walker ( Node * node,
void * found )
static

Walker for expr_contains_aggref.

Definition at line 21844 of file provsql.c.

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

◆ count_agg_body_sublinks()

int count_agg_body_sublinks ( Node * node)
static

The number of scalar subquery expressions with an aggregate body in node.

Definition at line 25203 of file provsql.c.

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

◆ count_agg_body_sublinks_walker()

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

Walker: count the scalar subquery expressions with an aggregate body in node (not in their bodies).

Definition at line 25188 of file provsql.c.

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

◆ count_cte_refs_walker()

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

Walker: count the references to a CTE of an enclosing query.

Definition at line 13924 of file provsql.c.

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

◆ cte_is_data_modifying()

bool cte_is_data_modifying ( const CommonTableExpr * cte)
static

Definition at line 3189 of file provsql.c.

Here is the caller graph for this function:

◆ cte_reference_walker()

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

Walker: does the tree contain an RTE_CTE reference to a CTE of the given name?

Descends into subquery RTEs, SubLink subselects and nested WITH bodies, so a reference anywhere inside a CTE body is found. Matching is by name only: a nested WITH shadowing the name yields a false positive, which errs on the side of inlining the referenced CTE (the uniform behaviour before untracked CTEs were preserved).

Definition at line 2487 of file provsql.c.

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

◆ cume_dist_mutator()

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

Mutator: each cume_dist() becomes the ratio of counts it is.

cume_dist() OVER w is the number of rows up to the current row's peers over the number of rows of the partition. The first is count(*) OVER w – the default frame of a window with an ORDER BY is RANGE UNBOUNDED PRECEDING AND CURRENT ROW, which holds exactly those rows, peers included – and the second the same count over the partition with no ordering. Both are aggregates ProvSQL tracks, so the ratio is tracked where the window function itself was read as a plain value; each is read as double precision, the type cume_dist answers in, so the value prints what SQL prints.

Definition at line 26840 of file provsql.c.

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

◆ decorr_value_sublink_walker()

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

Definition at line 12634 of file provsql.c.

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

◆ decorrelate_scalar_sublinks()

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

Decorrelate scalar subqueries into a LEFT JOIN with grouping.

Accepted, in a CMD_SELECT:

  • one EXPR_SUBLINK that is a target-list entry, or sits in a target-list entry under agg_token arithmetic only (the sublink becomes a choose() in place and the arithmetic carries its token), or is a direct operand of a comparison in a WHERE conjunct (the conjunct moves to HAVING);
  • or several target-list sublinks with the same body relation and correlation, differing in the value only, which share one LEFT JOIN (single base relation in the outer FROM only).

The body is "SELECT val FROM Q [WHERE corr]" with one non-junk output column, where val is:

  • a plain value: choose(val) with the group restricted by count(key) <= 1;
  • DISTINCT val: the restriction becomes count(DISTINCT val) <= 1;
  • a value with ORDER BY … LIMIT 1: choose(val ORDER BY key), no count restriction;
  • a single bare aggregate: that aggregate over the group, count(*) rewritten to count the matched rows only.

A body over several relations is first collapsed into one derived cross-product (oj_wrap_body_from), and an outer FROM that is not a single tracked relation or non-LATERAL subquery is wrapped into one (oj_wrap_outer_from). A value body, or count(*), needs a correlation on a column of Q; a non-star aggregate body does not. Declined: any other LIMIT / OFFSET, a CTE in the body, a sublink nested in anything other than the arithmetic above.

Returns
true if the query was rewritten in place; false leaves it untouched for the caller's handling of unsupported sublinks.

Definition at line 19710 of file provsql.c.

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

◆ deviation_as_arithmetic()

Node * deviation_as_arithmetic ( Aggref * ar,
const constants_t * constants )
static

stddev / variance of ar as the arithmetic over sum, sum of squares and count that defines it, or NULL.

PostgreSQL computes these with an accumulator of its own, which the provenance machinery has no reading of: the result is a value per world and nothing carries it. Their definition is arithmetic over aggregates that ARE carried,

var_samp(x) = (count(x)*sum(x*x) - sum(x)^2) / (count(x)*(count(x)-1))
var_pop(x) = (count(x)*sum(x*x) - sum(x)^2) / (count(x)*count(x))
stddev(x) = var(x) ^ 0.5

in that shape and no other: PostgreSQL divides once, at the end, and a form that divides earlier rounds differently – 2.333...34 where PostgreSQL prints 2.333...33. and over an EXACT argument type (an integer, a numeric) that arithmetic is the same number PostgreSQL's own accumulator gives, digit for digit. Over a floating-point one it need not be, so those are left as they were.

The guard is what a group of too few rows needs: var_samp divides by count-1, which is 0 where the group has one row, and SQL answers NULL there rather than raising. Over the possible worlds such a group is the common case, not an edge one, so the guard is a CASE the aggregate-case lowering carries (its condition compares a count with a constant).

Definition at line 6041 of file provsql.c.

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

◆ deviation_mutator()

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

Mutator: each stddev / variance as the arithmetic it is.

Definition at line 7797 of file provsql.c.

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

◆ distinct_on_lowerable()

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

Whether the DISTINCT ON of q is rewritten into the filter of a rank (lower_distinct_on_to_rank): a query that keeps its input rows, keys and order on values that are the same in every world.

Definition at line 26040 of file provsql.c.

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

◆ distinct_over_windows()

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

Move the window values of a SELECT DISTINCT into a subquery.

DISTINCT becomes a GROUP BY on every output column, and a window value cannot be a grouping key, windows being computed after grouping: SELECT DISTINCT a, count(*) OVER (...) is rewritten as the DISTINCT, ORDER BY and LIMIT of the query over the query without them; its junk entries, keys of its windows, stay in the subquery. Returns NULL, leaving q alone, when an entry reads provenance(), which the rows of the subquery would not give.

Definition at line 25653 of file provsql.c.

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

◆ divisor_zero_gate()

FuncExpr * divisor_zero_gate ( Node * divisor,
const constants_t * constants,
bool want_zero )
static

The gate of "expr IS NULL" (want_null) or of "expr IS NOT NULL", where arg is an expression over aggregates rather than an aggregate itself.

An aggregate's own NULL-ness is what having_NullTest_to_provenance reads, from the rows its group holds. Everything built over aggregates says how its NULL-ness follows from theirs:

  • a lowered CASE (agg_case, which a COALESCE, a NULLIF and a GREATEST / LEAST also become) is NULL exactly where the arm it selects is, so the reading is "⊕ᵢ (⊗ⱼ<ᵢ ¬gⱼ) ⊗ gᵢ ⊗ null(vᵢ)" over the arms and the default – first-match, as the gate itself is;
  • arithmetic over agg_tokens is strict: NULL where one operand is, so ⊕ over the operands for IS NULL and ⊗ for IS NOT NULL;
  • a value lifted into a value gate is the same in every world, so its NULL-ness is the deterministic indicator of the ordinary test (and, for a constant, 𝟙 or 𝟘 outright: the NULL branch of a NULLIF is one).

Returns NULL where the expression is none of these, or where an aggregate inside it has no reading of its own – the caller then leaves what it was lowering as the query wrote it, and the value is read as a plain one. This function never raises: declining is how it says no.

The gate of "this divisor reads zero in this world", or of "it does not" (want_zero false), or NULL where it cannot be built.

A division is NULL where an operand is – which is every operand's own reading – and ALSO where the divisor reads zero. That second condition is no operand's nullness but a COMPARISON of the divisor against zero, per world: a divisor that cancels in one world and not in another is null there and not here, so it explodes into the truths the worlds give it rather than settling on the divisor the data as it is displays. SQL RAISES there instead of answering NULL; the NULL is the algebra's totalization of a function undefined at zero (semantics, \S aggexpr), which is the convention to argue with if anyone objects, not this gate.

A divisor that is itself an agg_token gets the comparison gate the HAVING machinery builds for an aggregate against a constant; a plain one is the same number in every world, so an ordinary indicator on "divisor = 0" says it.

Definition at line 5509 of file provsql.c.

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

◆ drop_semijoin_distinct_walker()

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

Walker: drop the DISTINCT of the bodies of EXISTS, IN and quantified-comparison subqueries.

Whether a row, or a value, is there does not depend on how many times: the DISTINCT changes nothing to the test, and the rewritings of these subqueries, which refuse it, apply without it. (Not DISTINCT ON, which chooses rows.) The query's own level only: nested queries have their turn.

Definition at line 17505 of file provsql.c.

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

◆ error_for_mixed_qual()

void error_for_mixed_qual ( qual_class c)
static

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

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

Definition at line 20966 of file provsql.c.

Here is the caller graph for this function:

◆ except_all_on_provenance_walker()

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

Walker: is there, anywhere in the statement as the user wrote it, an EXCEPT ALL over provenance-tracked relations?

SQL's EXCEPT ALL removes as many copies of a tuple as the right operand has; which copies go is unspecified, so no copy has a provenance of its own, and the condition for the j-th copy to survive is a count over all the tuples of both sides. The difference of the algebra (each left tuple loses the ⊕ of the equal right tuples, the NOT IN reading) is not that operator: its rows differ from SQL's as soon as the left operand has duplicates. It remains what EXCEPT, NOT IN, antijoins and outer-join padding are built from, as internal EXCEPT ALL nodes the rewriting creates after this check; the SQL construct itself is refused.

Definition at line 29132 of file provsql.c.

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

◆ except_arm_column()

Expr * except_arm_column ( RangeTblEntry * rte,
Var * arg,
Var * v )
static

arg, a column of the EXCEPT arm rte, with the type of that column, coerced to the type of the set operation's column v.

Definition at line 14289 of file provsql.c.

Here is the caller graph for this function:

◆ except_column_is_aggregate_result()

bool except_column_is_aggregate_result ( const constants_t * constants,
RangeTblEntry * rte,
AttrNumber attno )
static

Whether column attno of the EXCEPT arm rte is the result of an aggregate (expr_is_aggregate_result): not compared, the other columns determining it.

Definition at line 14323 of file provsql.c.

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

◆ explode_setop_arms()

bool explode_setop_arms ( Query * q,
const constants_t * constants,
Node * n,
List * cols )
static

Explode column attno of every arm of the set-operation tree n of q.

A set operation reads its rows from its arms, so the values are exploded in each arm rather than in its result: a UNION would give the same rows either way, but a difference matches its rows on those values, and matching on the value of an aggregate – one per world – is what the explosion is there to replace.

Returns
Whether every arm was exploded.

Definition at line 23196 of file provsql.c.

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

◆ explode_value_of_text()

Node * explode_value_of_text ( Node * txt,
Oid value_type )
static

The text of an exploded value cast to the type of the aggregate.

agg_possible_values returns the values as text, whatever the type of the aggregate: an I/O cast reads each back, as the value of a frozen aggregate is read (frozen_agg_value).

Definition at line 23170 of file provsql.c.

Here is the caller graph for this function:

◆ expose_outer_refs_walker()

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

Walker: expose in ctx->base.inner the Vars of its level that the subquery expressions in node read (ctx->depth levels up from where the walk is).

Definition at line 25251 of file provsql.c.

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

◆ expr_as_text()

Expr * expr_as_text ( Expr * e)
static

e as text, through its output function.

Grouping and matching on a column whose type has no equality (json, xml, point...) are done on its text: the copies of a value that the rewriting compares come from the same row, hence have the same text.

Definition at line 17253 of file provsql.c.

Here is the caller graph for this function:

◆ expr_contains_agg()

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

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

Definition at line 4744 of file provsql.c.

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

◆ expr_contains_aggref()

bool expr_contains_aggref ( Node * node)
static

Whether an expression contains a plain Aggref.

expr_contains_agg recognises the shapes the rewriting has already produced (an agg_token Var, a provenance_aggregate call); this one runs before that, when the aggregate is still the parser's own node.

Definition at line 21864 of file provsql.c.

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

◆ expr_contains_aggref_walker()

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

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

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

Definition at line 11474 of file provsql.c.

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

◆ expr_contains_rv_cmp()

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

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

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

Definition at line 7092 of file provsql.c.

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

◆ expr_has_probabilistic_cmp()

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

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

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

Definition at line 6808 of file provsql.c.

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

◆ expr_is_aggregate_result()

bool expr_is_aggregate_result ( const constants_t * constants,
Query * q,
Node * e )
static

Whether e, an expression of q, is the result of an aggregate: an agg_token, or, not rewritten yet, an aggregate of a subquery it reads or a subquery expression, through subqueries and joins.

Such a value is a function of the other columns of its row (the grouping keys, the columns its subquery reads): matching or grouping rows on those suffices, and on it would compare aggregates.

Definition at line 20328 of file provsql.c.

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

◆ expr_provably_not_null()

bool expr_provably_not_null ( Node * e,
const Query * q,
Index levelsup )
static

Conservative provably-not-NULL test for the sublink lift.

True only for a non-NULL constant or (through binary-compatible coercions) a Var on a base-relation column declared NOT NULL, resolved in q at levelsup. Everything else – expressions, subquery outputs, outer-join-nullable Vars – conservatively counts as nullable.

Definition at line 17172 of file provsql.c.

Here is the caller graph for this function:

◆ extract_quantified_corr()

Node * extract_quantified_corr ( SubLink * sl,
bool * antijoin,
bool neg,
const Query * outerq,
bool * guarded )
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…).

NULL semantics: when the lift's final sense is the antijoin (neg XOR the base ALL sense – NOT IN, op ALL, NOT (op ANY)), a subquery row makes the outer row a non-answer not only when the correlation is true but also when it is unknown (SQL's 3VL: negation fixes u and the top level then filters it), i.e. when either operand is NULL. Each conjunct therefore becomes "(xᵢ ¬op qᵢ) OR xᵢ IS NULL OR qᵢ IS NULL", with the per-side guards omitted when that side is provably non-nullable (the common NULL-free path keeps its current form). The semijoin sense needs no guards: matching only the rows where the correlation is true is exactly SQL's own conflation of u with f at the top level. *guarded reports whether any guard was emitted (the caller must then re-key the count through oj_wrap_body_with_match_ind).

Definition at line 17373 of file provsql.c.

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

◆ fix_type_of_aggregation_result()

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

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

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

An aggregate result reaches an enclosing query either directly, as the subquery's own provenance_aggregate call, or forwarded by an intermediate subquery that merely selects it – in which case the deeper level's own pass (process_query recurses before this runs) has already retyped that intermediate Var. Both shapes are recognised by the column's type being agg_token, which is what carries the retyping through arbitrarily many levels of nesting: keying on the producing FuncExpr instead stops at the first level, leaving the column declared as its pre-rewrite scalar type, and a comparison against it is then executed natively on the raw composite datum.

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

Definition at line 1012 of file provsql.c.

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

◆ flat_origin1()

FlatAtomOrigin * flat_origin1 ( int slot)
static

A depth-1 origin path [slot].

Definition at line 23906 of file provsql.c.

Here is the caller graph for this function:

◆ flat_origin_prepend()

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

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

Definition at line 23915 of file provsql.c.

Here is the caller graph for this function:

◆ flatten_join_aliases()

void flatten_join_aliases ( Query * q)
static

Replace the Vars of join RTEs in the expressions of q by the columns of the joined relations (before PostgreSQL 13, the parser builds a column read through a join as a Var of the join).

Definition at line 15327 of file provsql.c.

Here is the caller graph for this function:

◆ flatten_mut()

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

Tree mutator implementing the conjunctive inlining of SPJ subqueries.

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

Definition at line 23867 of file provsql.c.

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

◆ flatten_spj_subqueries()

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

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

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

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

Definition at line 23952 of file provsql.c.

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

◆ flatten_union_descendants()

void flatten_union_descendants ( Node * node)
static

Make every UNION reachable from node through UNION nodes an ALL.

Used below a non-ALL UNION, whose outer GROUP BY deduplicates the whole subtree at once.

Definition at line 11730 of file provsql.c.

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

◆ formal_arg_type()

Oid formal_arg_type ( Form_pg_proc procForm,
int i )
static

The type of parameter i of a function, provariadic for the arguments a VARIADIC parameter spreads over (json_build_object's "any"), or InvalidOid.

Definition at line 10087 of file provsql.c.

Here is the caller graph for this function:

◆ freeze_agg_token_args()

bool freeze_agg_token_args ( Aggref * agg,
const constants_t * constants )
static

Read the inner aggregate's value as a plain value inside agg: replace each agg_token argument by its frozen value, of the type the aggregate was resolved on.

The outer aggregate is then an ordinary aggregate over plain numbers, over the rows of the subquery with their provenance: it gets an agg gate whose contributions carry values, so a comparison on it, a moment, an expected read it as they read any aggregate. That is what an explicit ::numeric on the inner aggregate does; here ProvSQL inserts it, and reports the frozen value once for the statement.

Returns
False where the token is read in a position this does not cover (a FILTER, an ORDER BY or a DISTINCT inside the aggregate), which stays refused.

Definition at line 870 of file provsql.c.

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

◆ freeze_relations_walker()

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

Walker: the base relations of the tracked relations read in a tree, but in ctx->skip.

Definition at line 13525 of file provsql.c.

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

◆ frozen_agg_value()

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

The value of the agg_token arg as a target_type, read by ProvSQL where the query reads a plain value.

Through agg_token_frozen_value, which does not warn: the planner reports the statement's frozen values once, where it finds that function (report_frozen_agg_values). NULL on a schema without it.

Definition at line 528 of file provsql.c.

Here is the caller graph for this function:

◆ frozen_agg_value_walker()

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

Walker: a value of an aggregate result read by ProvSQL as a plain value (frozen_agg_value), at any level.

Definition at line 13746 of file provsql.c.

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

◆ get_agg_token_orig_type()

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

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

The type of the aggregate the Var's subquery column comes from (orig_agg_type_of_var).

Definition at line 21207 of file provsql.c.

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

◆ get_provenance_attributes()

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

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

Walks every RTE in q->rtable:

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

Definition at line 3398 of file provsql.c.

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

◆ group_key_var()

Var * group_key_var ( Query * q,
TargetEntry * te )
static

The column te groups by, or NULL if it is no plain column.

PG 18 reads a grouping key through a virtual RTE_GROUP entry holding the key expressions, so the Var of such a target entry addresses that entry and not the relation the key comes from: follow it to the column it groups by. Read where it is needed rather than normalised away once, because the deparsing of a query resolves those Vars in place (a query looked at with provsql.verbose_level at 20 would otherwise be rewritten differently from the same query run quietly).

Definition at line 958 of file provsql.c.

Here is the caller graph for this function:

◆ group_set_difference_right_arm()

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

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

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

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

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

SELECT cols FROM (rarg) GROUP BY cols

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

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

Definition at line 20388 of file provsql.c.

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

◆ grouping_set_mutator()

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

Mutator: the value of an expression in the rows of one grouping set.

A grouping expression not in the set is NULL there, but for the aggregates, which read the input rows; GROUPING(a, b, ...) is the constant whose bits, from the left, say which of its arguments are not in the set.

Definition at line 12062 of file provsql.c.

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

◆ has_aggtoken()

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

Return true if node contains a Var of type agg_token.

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

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

Definition at line 14105 of file provsql.c.

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

◆ has_outer_join_walker()

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

Walker: an outer join in a join tree.

Definition at line 26242 of file provsql.c.

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

◆ has_provenance()

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

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

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

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

Definition at line 12793 of file provsql.c.

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

◆ has_provenance_walker()

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

Definition at line 12674 of file provsql.c.

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

◆ has_rv_or_provenance_call()

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

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

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

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

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

Definition at line 12475 of file provsql.c.

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

◆ having_BoolExpr_to_provenance()

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

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

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

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

Definition at line 5849 of file provsql.c.

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

◆ having_entails_group_existence()

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

Whether a lifted HAVING predicate already entails that the group exists.

A comparison on an aggregate does: the possible-world enumeration behind its gate_cmp ranges over the non-empty worlds of the group's own tokens, so the gate is 0 wherever the group is empty. That is what lets the lift supersede the group's δ instead of multiplying with it.

An aggregate-free atom does not. Its predicate-provenance is the deterministic indicator regular_indicator, which is 1 or 0 by the value of a grouping column and says nothing about whether any row is present. Superseding the δ in front of one would claim the group exists in every world – so HAVING count(*) >= 4 OR g = 1 would report certainty for a group that is empty half the time.

The two combine as the semiring does: under ⊗ one entailing factor makes the product entail (the other factor cannot resurrect an empty group), while under ⊕ every disjunct must entail, since any one of them alone can make the sum non-zero. negated tracks De Morgan, matching having_BoolExpr_to_provenance: the complement of an aggregate comparison is another comparison over the same non-empty worlds, so negation preserves entailment at the atoms.

Definition at line 14187 of file provsql.c.

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

◆ having_Expr_to_provenance_cmp()

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

Dispatch a HAVING sub-expression to the appropriate converter.

Entry point for the mutual recursion between having_BoolExpr_to_provenance and having_OpExpr_to_provenance_cmp.

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

Definition at line 5899 of file provsql.c.

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

◆ having_int_const()

Node * having_int_const ( int32 v)
static

The int4 constant v, for a bound this relaxes by one.

Definition at line 6241 of file provsql.c.

Here is the caller graph for this function:

◆ having_lift_walker()

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

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

Returns true on:

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

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

Definition at line 14125 of file provsql.c.

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

◆ having_null_filtered_plus()

FuncExpr * having_null_filtered_plus ( const constants_t * constants,
Aggref * base_arr,
Node * K,
Expr * cond )
static

Build "⊕(array_agg(K) FILTER (WHERE cond))" – the per-row provenance ⊕ over the rows of an aggregate's group that satisfy cond.

base_arr is the aggregate's array_agg(provenance_semimod(V, K)) Aggref; we copy it, swap its argument to K, and set its FILTER to cond (which replaces the user's FILTER that base_arr carries for a NULL-keeping aggregate: the caller folds it into cond). The filtered array_agg is NULL (not an empty array) for a group with no such row, so it is wrapped in COALESCE(..., '{}') – the STRICT provenance_plus then yields gate_zero rather than NULL.

Definition at line 5117 of file provsql.c.

Here is the caller graph for this function:

◆ having_NullTest_to_provenance()

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

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

sum / avg / min / max / 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 the others (V IS NULL → tokens Kz, present but not contributing); a FILTER is already folded into V by make_aggregation_expression. A NULL-keeping aggregate (array_agg, ...) is instead NULL exactly when it reads no row at all: its value rows are the rows passing its FILTER (all rows without one), whatever their value. 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 5250 of file provsql.c.

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

◆ having_OpExpr_to_provenance_cmp()

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

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

Each argument of opExpr must be one of:

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

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

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

Definition at line 4992 of file provsql.c.

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

◆ having_possible()

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

Condition under which the HAVING predicate expr may hold in some world, or NULL when nothing is known (it may always hold).

Follows having_Expr_to_provenance_cmp: negation is pushed to the atoms, exchanging AND and OR. A conjunction keeps what is known of its parts; a disjunction is known only if every part is. A regular atom is its own condition.

Definition at line 6534 of file provsql.c.

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

◆ having_possible_atom()

Expr * having_possible_atom ( OpExpr * op,
const constants_t * constants,
bool negated )
static

Definition at line 6404 of file provsql.c.

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

◆ having_possible_carried()

Expr * having_possible_carried ( OpExpr * op,
const constants_t * constants,
bool negated,
bool * handled )
static

The PostgreSQL-evaluable necessary condition of a comparison whose aggregate side is read by a function ProvSQL carries (floor, ceil, round, abs), or NULL where there is none.

The rows of the answer are SQL's, so a group in which the comparison holds in no world is dropped by a condition PostgreSQL evaluates on the data as it is. having_possible_atom builds one from the aggregate, which it needs as the compared side; here a function stands in between, and the comparison is relaxed to see through it, which a necessary condition may be:

  • floor, ceil and round move a value by less than one, so the comparison implies the same one on the aggregate with the bound moved by one in the permissive direction. A round to a number of digits moves it by less still while that number is not negative (round(v, -2) moves a value by up to 50), so a negative or non-constant one declines.
  • abs reaches a bound where the aggregate reaches it or its opposite, so the condition is the disjunction of the two comparisons (their conjunction where the bound is from above).
Parameters
handledSet when the shape is one of these, whether or not a condition comes out of it.

Definition at line 6282 of file provsql.c.

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

◆ having_reuse_op()

OpExpr * having_reuse_op ( OpExpr * op,
Oid opno,
Node * agg_side,
Node * c,
bool agg_on_left )
static

op with its two arguments replaced, the same operator.

Definition at line 6247 of file provsql.c.

Here is the caller graph for this function:

◆ having_side_aggref()

Aggref * having_side_aggref ( Node * node,
const constants_t * constants )
static

Definition at line 5972 of file provsql.c.

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

◆ hide_plain_provsql_columns()

void hide_plain_provsql_columns ( Query * q)
static

Hide, in the target list of q, the entries reading the provenance placeholder of a plain(NULL::t) source (the provsql column of a *): made junk, moved last, so that the other columns keep their positions.

For the statement itself, whose columns only its client reads.

Definition at line 13427 of file provsql.c.

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

◆ hide_provsql_colname()

void hide_provsql_colname ( RangeTblEntry * rel)
static

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

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

Definition at line 14575 of file provsql.c.

Here is the caller graph for this function:

◆ hide_provsql_in_wholerows()

void hide_provsql_in_wholerows ( const constants_t * constants,
Query * q,
bool top_level )
static

Leave the provsql column out of the whole-row values of provenance-tracked relations where any row is read.

The row type of a tracked table has its provsql column, so that row_to_json(t), t::text or json_agg(t.*) show the token of the row, which is not data. Where the value is read as any row – the output of the statement shown to the user (not stored by a CREATE TABLE AS, nor returned by a function), a parameter of type record, "any" or polymorphic with a result type of its own (the json functions), a conversion to text – it becomes the anonymous record of the other columns. Where the table's own row type is needed (t::tbl, a function on it, a comparison of rows), it stays. Runs on the query and the bodies of its sublinks, before the rewriting that would otherwise meet the whole-row value.

Definition at line 26467 of file provsql.c.

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

◆ holds_node_walker()

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

Walker: is target one of the nodes of the tree, by address?

Definition at line 13672 of file provsql.c.

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

◆ inert_fetch_sublink_walker()

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

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

Definition at line 12601 of file provsql.c.

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

◆ inline_ctes()

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

Definition at line 3194 of file provsql.c.

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

◆ inline_ctes_in_rtable()

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

Inline CTE references as subqueries within a query.

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

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

Definition at line 2529 of file provsql.c.

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

◆ inline_ctes_in_sublinks_walker()

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

Walker: inline the CTE references of the subqueries of sublinks (IN, EXISTS, scalar subqueries), at any depth.

inline_ctes_in_rtable follows the range tables; a CTE read from a sublink would otherwise keep a reference to a CTE no longer in the WITH clause.

Definition at line 3168 of file provsql.c.

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

◆ inner_join_collect()

bool inner_join_collect ( Node * jt,
List ** refs,
List ** quals,
Bitmapset ** joins )
static

Recursively collect an all-inner join tree's leaf RangeTblRefs, ON quals, and dissolved RTE_JOIN rtindexes.

Returns false – leaving the outputs unusable – on any outer join, aliased join (JOIN ... AS, whose column renaming the flat form cannot carry), or unexpected node.

Definition at line 24764 of file provsql.c.

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

◆ insert_agg_token_casts()

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

Walk query and insert agg_token casts where needed.

Definition at line 21599 of file provsql.c.

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

◆ insert_agg_token_casts_mutator()

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

Insert agg_token casts for Vars used in expressions.

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

Definition at line 21394 of file provsql.c.

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

◆ insert_having_agg_token_casts_mutator()

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

insert_agg_token_casts_mutator for the HAVING clause.

Its comparisons read their aggregates as they are, the HAVING lowering building their gates from them: an operator is swapped for its agg_token version or has its subquery aggregate columns cast, and its arguments are left alone.

Definition at line 21562 of file provsql.c.

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

◆ intersect_column()

Expr * intersect_column ( Query * side,
Index varno,
AttrNumber attno,
Oid type,
int32 typmod )
static

Column attno of the side side (range-table entry varno), coerced to the type of the column of the set operation.

Definition at line 11836 of file provsql.c.

Here is the caller graph for this function:

◆ intersect_side()

Query * intersect_side ( Node * node,
List * rtable )
static

A side of an INTERSECT, as a subquery: a leaf, or a set operation made a query of its own.

Definition at line 11827 of file provsql.c.

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

◆ inv_free_arm_head_vars()

List * inv_free_arm_head_vars ( Query * arm)
static

The output (head) columns of a UNION arm as plain base Var\ s.

Returns a list of the Var behind each non-junk target entry (stripping RelabelType), or NIL if any output column is not a bare Var – the UCQ head classes can only be aligned across arms through column Var\ s.

Definition at line 24311 of file provsql.c.

Here is the caller graph for this function:

◆ inv_free_make_eq()

OpExpr * inv_free_make_eq ( Var * v1,
Var * v2 )
static

Build the equality qual v1 = v2, or NULL if the types have no = operator.

Definition at line 24331 of file provsql.c.

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

◆ is_actual_marker()

bool is_actual_marker ( const constants_t * constants,
Node * n )
static

Whether n is a call of the marker plain(), up to coercions.

Definition at line 24990 of file provsql.c.

Here is the caller graph for this function:

◆ is_comparison_opno()

bool is_comparison_opno ( Oid opno)
static

Is opno one of the six comparison operators by name?

Definition at line 19505 of file provsql.c.

Here is the caller graph for this function:

◆ is_const_or_param()

bool is_const_or_param ( Node * n)
static

Whether n is a constant or a parameter, up to coercions.

Definition at line 25068 of file provsql.c.

Here is the caller graph for this function:

◆ is_inert_subselect()

bool is_inert_subselect ( Query * q)
static

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

Definition at line 12554 of file provsql.c.

Here is the caller graph for this function:

◆ is_movable_uncorrelated_sublink()

bool is_movable_uncorrelated_sublink ( const constants_t * constants,
TargetEntry * te,
List * ctes )
static

Is te a scalar subquery that move_uncorrelated_sublinks_to_from moves to the FROM?

Definition at line 25725 of file provsql.c.

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

◆ is_null_constant_operand()

bool is_null_constant_operand ( Node * node)
static

True when node is a NULL constant (through a coercion).

Detects the literal NULL operand of a lifted comparison at planning time; a NULL flowing in at execution (a NULL random_variable cell) is caught by provenance_cmp instead.

Definition at line 6653 of file provsql.c.

Here is the caller graph for this function:

◆ is_projected_rv_event()

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

Is node a projected random_variable comparison event?

True when the (target-list) expression is itself a random_variable comparison – a bare RV comparator OpExpr, or a Boolean combination of RV comparisons (optionally mixed with ordinary comparisons) carrying at least one RV comparison. Such an expression is lifted into its event token (a gate_cmp uuid) so "SELECT x > y" surfaces the event rather than raising inside random_variable_cmp_placeholder. Deterministic Booleans and agg-only comparisons are left untouched.

Definition at line 7857 of file provsql.c.

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

◆ is_provsql_column()

bool is_provsql_column ( const constants_t * constants,
Query * q,
Node * n )
static

Whether n is a column named provsql of type uuid of an entry of q's range table.

Definition at line 26122 of file provsql.c.

Here is the caller graph for this function:

◆ is_provsql_column_var()

bool is_provsql_column_var ( List * rtable,
Var * v )
static

Whether v, a Var of range table rtable, is the provsql column of its relation: a subquery exposing it keeps that name, so that it drops it as any provenance column of its target list.

Definition at line 15397 of file provsql.c.

Here is the caller graph for this function:

◆ is_supported_bool_agg()

bool is_supported_bool_agg ( Oid aggfnoid)
static

Definition at line 14240 of file provsql.c.

Here is the caller graph for this function:

◆ is_target_agg_var()

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

Check if a Var matches the target aggregate column.

Definition at line 507 of file provsql.c.

Here is the caller graph for this function:

◆ join_alias_resolve_mut()

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

Mutator: replace every Var referencing a dissolved join RTE by its joinaliasvars expression – resolved recursively, since chained joins alias through each other – adjusted to the Var's level.

This covers USING / NATURAL merged columns and aliased ON-join columns alike.

Definition at line 24732 of file provsql.c.

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

◆ join_qual_has_agg_token()

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

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

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

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

Definition at line 21666 of file provsql.c.

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

◆ join_qual_has_agg_token_walker()

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

Definition at line 21617 of file provsql.c.

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

◆ join_tree_has_outer_join()

bool join_tree_has_outer_join ( Node * n)
static

Whether n is a join tree containing an outer join.

Definition at line 15550 of file provsql.c.

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

◆ join_tree_rtindexes()

void join_tree_rtindexes ( Node * n,
Bitmapset ** idx )
static

Collect the range-table indexes of a join tree (its relations and its joins).

Definition at line 15346 of file provsql.c.

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

◆ join_wholerow_walker()

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

Walker: does any Var reference a dissolved join RTE as a whole row (varattno <= 0)?

Such a reference cannot be resolved through joinaliasvars, so the normalization declines.

Definition at line 24707 of file provsql.c.

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

◆ jointree_arm_has_tracked()

bool jointree_arm_has_tracked ( const constants_t * constants,
Query * q,
Node * n )
static

Walker: does the jointree fragment n reference a provenance-tracked RTE of q?

Join arms are RangeTblRef leaves or nested JoinExpr nodes. Base relations and subqueries are tested with oj_rte_has_provsql; any other RTE kind (CTE, function, VALUES) counts as tracked when its eref exposes a provsql column, the same name convention the provenance discovery matches on.

Definition at line 15234 of file provsql.c.

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

◆ keep_only_provenance_output()

void keep_only_provenance_output ( Query * sub)
static

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

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

Definition at line 24575 of file provsql.c.

Here is the caller graph for this function:

◆ lift_body_outer_only_conjuncts()

bool lift_body_outer_only_conjuncts ( Query * sub)
static

Lift the conjuncts of an inner sublink body's WHERE that read nothing of that body's own relations into the qual holding the sublink.

The mirror of wrap_body_sublinks, which moves the conjuncts that read nothing OUTSIDE a body into a derived table of it. Here it is the other half: a conjunct of "id IN (SELECT id FROM posts WHERE p2.answercount > 0 AND p2.tags = p.tags)" reads only the levels ABOVE the body, so it takes the same value for every row the body scans and can be evaluated one level up:

x IN (SELECT a FROM Q WHERE t IN (SELECT b FROM R WHERE C)) C outer-only x IN (SELECT a FROM Q WHERE C AND t IN (SELECT b FROM R))

What that buys is the inner test becoming UNCORRELATED, which rewrite_uncorrelated_membership then lowers, leaving the outer body plain for the decorrelation – where before, the outer test was refused with body-nested-subquery (difftest's sede/f42f1b3271, F1).

Two shapes are declined rather than lifted. A NEGATED test, because the equivalence fails on a NULL C: the body is empty either way, so the positive test is false either way and a WHERE filters the row, while under a NOT one reading is true and the other unknown. And a body that AGGREGATES without grouping, because such a body yields a row over no input at all – "x IN (SELECT count(*) FROM R WHERE C)" answers over the count 0 where C is false, and pulling C out would make it answer nothing.

Returns
Whether anything was lifted.

Definition at line 16518 of file provsql.c.

Here is the caller graph for this function:

◆ lift_rv_event_mutator()

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

Mutator: lift any random_variable comparison event to its token.

Run as a second pass over the target list, after rewrite_probability_event_mutator has lowered the RV surface (GREATEST / LEAST, RV CASE -> rv_case, probability(...)). By then a comparison's operands are already lowered and every RV CASE guard has been consumed into an rv_case token, so lifting a remaining bare RV comparison – "x <= c" wherever it appears, including nested inside a scalar/aggregate consumer such as expected(x <= c) – is safe. Without this the inner OpExpr survives to execution and raises in random_variable_cmp_placeholder (the placeholder exists precisely to catch a comparison the hook failed to lift).

Definition at line 7985 of file provsql.c.

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

◆ lift_tracked_sublinks()

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

Lift the tracked bodies of a block's sublinks into its FROM.

A block with no tracked relation of its own – "SELECT @c 'yes' @c WHERE @c EXISTS(...)", a VALUES list filtered by a NOT EXISTS – reads tracked relations only through its sublinks, and has_provenance does not descend into a sublink (a subselect in an expression is planned on its own). The block is then taken as untracked and none of the sublink rewrites run, although the semantics has the query: its condition is a semijoin or an antijoin over the bodies, whose provenance is the answer's.

What the block lacks is a range-table entry to hang the provenance on, and the very rewrites that are skipped are what would give it one. So they are run here, on a copy, before the planner decides: if they leave a tracked relation behind, that copy is the query to process; if not, nothing is lost and the block stays as it was, to be reported as evaluated by plain SQL.

Returns
The rewritten query, or NULL when the lift changed nothing that makes the block tracked.

Definition at line 29030 of file provsql.c.

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

◆ limit_lowerable()

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

Definition at line 25092 of file provsql.c.

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

◆ limit_truncates()

bool limit_truncates ( const Query * q)
static

Whether the LIMIT / OFFSET of q removes rows.

Definition at line 24999 of file provsql.c.

Here is the caller graph for this function:

◆ lower_distinct_on_to_rank()

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

Rewrite the DISTINCT ON of q into the filter of a rank, or return NULL if it is not.

SELECT DISTINCT ON (k) ... ORDER BY k, o keeps, for each value of k, the first row in the order of o: in each world, the rows with no present row of the same k before them, that is, row_number() OVER (PARTITION BY k ORDER BY o) <= 1, tracked as the rank it is when o leaves no ties (with a warning otherwise, as for LIMIT). The same conditions as limit_lowerable: keys and order on values that are the same in every world, a query that keeps its input rows. The ORDER BY, LIMIT and OFFSET apply to the result.

Definition at line 26072 of file provsql.c.

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

◆ lower_limit_to_rank()

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

Rewrite the LIMIT / OFFSET of q into the filter of a rank, or return NULL if it is not (limit_lowerable).

q, without its LIMIT and OFFSET, becomes the innermost query of

SELECT ... FROM (SELECT ..., row_number() OVER (ORDER BY ...) AS rk
FROM (q) limited_rows) limited
WHERE rk > m AND rk <= m + k ORDER BY ...
@ AND
Boolean AND aggregate.
Definition Aggregation.h:57

with rank() for WITH TIES; the enclosing comparison on the rank, an aggregate of the middle query once rewritten, goes into the annotation of each row. The rank is computed over the rows of q with their provenance, which includes what the WHERE of q contributes. q exposes the output columns and the sort keys; the entries that read provenance() move to the enclosing query, where the provenance of a row includes the comparison.

Definition at line 26015 of file provsql.c.

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

◆ lower_outer_joins()

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

Definition at line 15803 of file provsql.c.

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

◆ lower_to_rank_filter()

Query * lower_to_rank_filter ( const constants_t * constants,
Query * q,
List * partition,
List * order,
Node * count,
Node * offset,
bool ties,
List * outer_sort )
static

The core of lower_limit_to_rank and lower_distinct_on_to_rank: keep the rows of q whose rank, in the window of partition partition and order order, is above offset and at most offset + count (either may be NULL); rank() if ties, row_number() otherwise.

The enclosing query is sorted by outer_sort. q has no ORDER BY, LIMIT or OFFSET left of its own.

Definition at line 25843 of file provsql.c.

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

◆ make_aggregation_expression()

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

Build the provenance expression for a single aggregate function.

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

provenance_aggregate(fn_oid, result_type,
original_aggref,
array_agg(provenance_semimod(arg, times_or_monus_token)))
Datum provenance_aggregate(PG_FUNCTION_ARGS)
The agg gate of a group, paired with the aggregate's value.
Datum provenance_semimod(PG_FUNCTION_ARGS)
The semimodule gate val ⊗ token of an aggregated row.

COUNT(*) and COUNT(expr) feed the semimodule a per-row 1 / 0-or-1 value so the semimodule semantics (scalar × token → token) work, while the gate keeps the COUNT identity: only that distinguishes a count from a sum over the same values once the group is empty.

Parameters
constantsExtension OID cache.
agg_refThe original Aggref node from the query.
prov_attsList of provenance Var nodes.
opSemiring operation (determines how tokens are combined).
is_scalarAggregation has no GROUP BY (single always-present row).
plain_tokenThe row token the displayed value is filtered by (plain_row_token), or NULL.
Returns
Provenance expression of type agg_token.

Definition at line 4491 of file provsql.c.

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

◆ make_case_when()

Expr * make_case_when ( Expr * cond,
Expr * then_expr,
Expr * else_expr )
static

Build "CASE WHEN cond THEN then_expr [ELSE else_expr] END".

Definition at line 4302 of file provsql.c.

Here is the caller graph for this function:

◆ make_column_var()

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

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

Definition at line 23729 of file provsql.c.

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

◆ make_dense_rank_expression()

Expr * make_dense_rank_expression ( window_aggregation_context * c,
WindowFunc * wf )
static

The provenance expression of the dense rank of a row in the window of wf, 1 + the number of distinct ordering values strictly before it, or NULL.

An ordering value is present in a world when one of its rows is: the COUNT gate reads, for each distinct value of the rows strictly before, the ⊕ of their tokens, which window_distinct_tokens builds from the values and the tokens of that frame (window aggregates have no DISTINCT). The ordering values are those of the ORDER BY of the window, as a row value, so that several keys make one value.

Definition at line 11194 of file provsql.c.

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

◆ make_dense_rank_subquery()

Expr * make_dense_rank_subquery ( rank_window_ctx * ctx,
WindowFunc * wf )
static

The dense rank of the current row among those of ctx->rtindex, as a subquery counting the keys up to its own, or NULL.

dense_rank() OVER (PARTITION BY p ORDER BY k) is the number of distinct keys of the partition that do not come after the current row's:

(SELECT count(*)
FROM (SELECT DISTINCT b.p, b.k FROM R b) v
WHERE v.p IS NOT DISTINCT FROM a.p AND (v.k < a.k OR v.k = a.k))

The keys are deduplicated once, over the whole relation and every partition at once, so that the deduplication is not correlated: a correlated body that groups rows of its own is not tracked, whereas this one only compares. Over an aggregate result the deduplication is the explosion of that aggregate into one row per value it takes (rewrite_explode_agg_value), so v holds every value the key takes over the possible worlds, each with the provenance of taking it: in every world the rows of v are the keys of that world, and counting those up to the current row's is the dense rank there.

Ties need no identity column, unlike rank(): the current row's own key is one of the keys counted.

Definition at line 27427 of file provsql.c.

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

◆ make_null_safe_equality()

Node * make_null_safe_equality ( Expr * l,
Expr * r,
Oid type,
Oid collation,
bool nullable )
static

Build a comparison of l and r under which two NULLs are equal.

This is what set operations and GROUP BY mean by "the same value". The direct spelling, IS NOT DISTINCT FROM, is not an operator: PostgreSQL can neither hash nor merge on it, and a join on it is a nested loop, quadratic in the size of its inputs. Hence, in order of preference:

  • nullable false (one side at least is never NULL): plain "=";
  • "ARRAY[l] = ARRAY[r]": array equality takes two NULL elements as equal and compares the others with the element type's default equality, and it is an ordinary hashable and mergeable operator;
  • "NOT (l IS DISTINCT FROM r)" when the type has no array type, no default equality, or is itself an array (ARRAY[] of an array is a multidimensional array, not an array with one element).
Parameters
l,rthe two operands, of type type (not copied)
typetheir common type
collationcollation of the comparison, or InvalidOid
nullablefalse if one operand at least is known never to be NULL

Definition at line 17283 of file provsql.c.

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

◆ make_placeholder_rte()

void make_placeholder_rte ( RangeTblEntry * rte)
static

Make rte an empty placeholder: an entry of the range table no longer read (its relation moved to a subquery), which must neither be scanned nor count as a source of provenance.

Definition at line 15367 of file provsql.c.

Here is the caller graph for this function:

◆ make_provenance_attribute()

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

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

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

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

Definition at line 390 of file provsql.c.

Here is the caller graph for this function:

◆ make_provenance_expression()

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

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

Combines the tokens in prov_atts according to op:

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

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

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

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

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

Definition at line 8417 of file provsql.c.

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

◆ make_rank_expression()

Expr * make_rank_expression ( window_aggregation_context * c,
WindowFunc * wf )
static

The provenance expression of the rank of a row in the window of wf, 1 + the number of rows strictly before it, or NULL.

Definition at line 11165 of file provsql.c.

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

◆ make_rank_subquery()

Expr * make_rank_subquery ( rank_window_ctx * ctx,
WindowFunc * wf,
bool dense )
static

The rank of the current row among those of ctx->rtindex, as a subquery counting them, or NULL.

rank() OVER (PARTITION BY p ORDER BY k) is the number of rows of the same partition that come before the current one, itself included:

(SELECT count(*) FROM R b
WHERE b.p IS NOT DISTINCT FROM a.p
AND (b.k < a.k OR b.id IS NOT DISTINCT FROM a.id))

which is the rank with ties, since a row tying with the current one comes neither before it nor is it. The identity columns tell the current row from the others (the grouping columns of the relation ranked, which has one row per group), and a is the row of the enclosing query, read one level up.

Counting the current row spares an addition outside the subquery, which would leave the subquery in an expression, untracked.

Definition at line 27207 of file provsql.c.

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

◆ make_rank_window()

WindowFunc * make_rank_window ( Query * q,
WindowFunc * wf )
static

The number of rows strictly before the current one, as the aggregate count(*) over a window.

The rank of a row is one plus the number of rows strictly before it, the rows of the frame RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE GROUP. That window, a copy of the one of wf with this frame, is appended to q. The frame excludes the current row, so it may be empty (a count of 0, the scalar convention), and the count does not depend on the presence of the row, whose token multiplies the comparisons on it: the comparison evaluators see independent contributors, and fold the + 1 into their threshold.

Definition at line 11116 of file provsql.c.

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

◆ make_regular_indicator()

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

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

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

Definition at line 5446 of file provsql.c.

Here is the caller graph for this function:

◆ make_row_semimod()

FuncExpr * make_row_semimod ( const constants_t * constants,
Oid aggfnoid,
Expr * arg,
Expr * filter,
Expr * row_token )
static

The contribution of the current row to an aggregate gate: provenance_semimod of the value it adds and of its token.

Parameters
constantsExtension OID cache.
aggfnoidThe aggregate function.
argIts argument, NULL for count(*).
filterIts FILTER clause, or NULL. For an aggregate that keeps its NULL inputs, the caller puts the filter on the aggregation of the contributions instead.
row_tokenThe row's token (make_row_token).

Definition at line 4371 of file provsql.c.

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

◆ make_row_token()

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

The provenance token of the current row: its single provenance attribute, or their product (SR_TIMES) or difference (SR_MONUS).

Definition at line 4330 of file provsql.c.

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

◆ make_rv_aggregate_expression()

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

Inline rewrite of an RV-returning aggregate, baking each aggregate's identity element into the per-row provenance wrap.

Handles any aggregate whose result type is random_variable. Each row contributes mixture(prov_token, X_i, as_random(identity)), where the identity element is chosen per aggregate so the aggregate's final function is a plain fold with no gate inspection:

  • sum : identity 0 (additive), realising \(\mathrm{SUM}(x) = \sum_i \mathbf{1}\{\varphi_i\} \cdot X_i\);
  • product : identity 1 (multiplicative);
  • max / min : identity \(\mp\infty\) (order-statistic).

avg is special: it is rewritten to rv_sum_or_null(rv_aggregate_semimod(prov, x)) / sum(rv_aggregate_indicator(prov)) – the "AVG = SUM / COUNT" identity lifted into the random_variable algebra, with the provenance-weighted count as the denominator. Both sums ride on sum's fold, so avg too never inspects a gate.

Any RV aggregate not recognised here (a future addition, or an older schema whose helper OIDs are absent) falls back to the additive identity-0 wrap and its own aggfnoid, the historical behaviour.

Every aggregate rebuilt here carries the user's FILTER clause over: the result is a random_variable built from the rows the aggregate reads, so leaving PostgreSQL to drop the rows failing the filter is all it takes (an empty selection is NULL, as for an empty group).

Routing happens at make_aggregation_expression on agg_ref->aggtype == OID_TYPE_RANDOM_VARIABLE. SR_PLUS (UNION outer level) is handled by the caller; this builder never runs for it.

Definition at line 4051 of file provsql.c.

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

◆ make_uuid_array_subscript()

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

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

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

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

Definition at line 21687 of file provsql.c.

Here is the caller graph for this function:

◆ make_window_aggregation_expression()

Expr * make_window_aggregation_expression ( const constants_t * constants,
Query * q,
WindowFunc * wf,
List * prov_atts )
static

The provenance expression of an aggregate used as a window function, or NULL if it is not tracked.

f(x) OVER w,
array_agg(provenance_semimod(x, k)) OVER w,
is_scalar)

where k is the row's token and both window calls share the window w, so the gate aggregates the contributions of exactly the rows of the frame. This is make_aggregation_expression with the frame in place of the group: a whole-partition window gives, for each row, the gate of the GROUP BY on the partition attributes. The frame must be determined by values (window_frame_by_values).

Definition at line 11044 of file provsql.c.

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

◆ mark_col_selected()

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

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

Definition at line 23713 of file provsql.c.

Here is the caller graph for this function:

◆ mark_plain_inner_walker()

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

Walker: tag the subqueries of subquery expressions in node.

Definition at line 13308 of file provsql.c.

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

◆ mark_plain_sublinks_walker()

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

Walker: mark the subquery expressions inside a plain() call as inert, evaluated as plain SQL (PROVSQL_INERT_QUERY_ID).

Definition at line 13320 of file provsql.c.

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

◆ maybe_cast_agg_token_args()

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

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

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

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

Definition at line 10107 of file provsql.c.

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

◆ migrate_probabilistic_quals()

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

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

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

Supported shapes:

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

Definition at line 21023 of file provsql.c.

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

◆ minmax_agg_to_case()

CaseExpr * minmax_agg_to_case ( MinMaxExpr * mm,
const constants_t * constants )
static

Definition at line 7634 of file provsql.c.

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

◆ move_uncorrelated_sublinks_to_from()

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

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

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

Definition at line 19338 of file provsql.c.

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

◆ move_uncorrelated_where_predicates()

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

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

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

Definition at line 18706 of file provsql.c.

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

◆ moved_vars_mutator()

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

Mutator: a Var of a moved relation becomes a Var of the subquery's column exposing it, at any depth.

Definition at line 15411 of file provsql.c.

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

◆ na_body_relation()

RangeTblEntry * na_body_relation ( Query * b,
bool allow_sublink )
static

The single relation of b, where b is a body this pass can read: one base relation in its FROM, nothing else of its own.

Definition at line 17624 of file provsql.c.

Here is the caller graph for this function:

◆ na_copy_rel()

RangeTblEntry * na_copy_rel ( Query * to,
Query * from,
RangeTblEntry * src )
static

Copy the relation entry src of from into to, with its permission info.

Definition at line 17726 of file provsql.c.

Here is the caller graph for this function:

◆ na_corr_in_mut()

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

Mutator for the inner body, which keeps its level (one below the pair block): what read the body's relation and the query's own two and three levels up now read the block just above.

Definition at line 17701 of file provsql.c.

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

◆ na_corr_out_mut()

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

Mutator for the body's own correlation, one level below the query: what reads the body's relation (level 0, its only one) becomes p_new of the pair block, and what reads the query's own relations comes down a level, keeping the index it had – the pair block holds them at the same places.

Definition at line 17675 of file provsql.c.

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

◆ na_except_to_nested()

Query * na_except_to_nested ( const constants_t * constants,
Query * sub )
static

Read a "NOT EXISTS (A EXCEPT B)" body as the nested antijoin it is, and return the body to read in its place, or NULL.

"A EXCEPT B is empty" is "every row of A is a row of B" – the same division as a nested antijoin, written with a set operation instead of a second NOT EXISTS. So the arms are put back in that form:

NOT EXISTS (SELECT e FROM P WHERE qA EXCEPT SELECT f FROM C WHERE qB) = NOT EXISTS (SELECT 1 FROM P WHERE qA AND NOT EXISTS (SELECT 1 FROM C WHERE qB AND f IS NOT DISTINCT FROM e))

and rewrite_nested_antijoin then reads the result. The match is on all the arms' columns, NULL-safely, which is how a set operation compares rows.

EXCEPT ALL is a different question – it asks whether A has MORE copies of a row than B, not whether B has the row at all – and is declined. An arm of a set operation sits one level further down than a plain body, so what it reads of the query around comes up one level here.

Definition at line 17789 of file provsql.c.

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

◆ na_not_distinct()

Node * na_not_distinct ( Expr * l,
Expr * r )
static

"l IS NOT DISTINCT FROM r".

A plain = would miss a row with a NULL in the column, and let it through an antijoin it should not pass; it is also the matching a set operation does, which reads two NULLs as equal.

Definition at line 17743 of file provsql.c.

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

◆ na_not_exists()

SubLink * na_not_exists ( Node * n)
static

The NOT EXISTS SubLink of n, or NULL.

Definition at line 17647 of file provsql.c.

Here is the caller graph for this function:

◆ needs_having_lift()

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

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

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

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

Definition at line 14158 of file provsql.c.

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

◆ nest_set_operations()

bool nest_set_operations ( Query * q)
static

Entry point of nest_set_operations_rec for the query q.

Definition at line 12219 of file provsql.c.

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

◆ nest_set_operations_rec()

bool nest_set_operations_rec ( Node ** nodep,
SetOperationStmt * parent,
List * old_rtable,
List ** rtable )
static

Nest the set-operation subtrees that the rewriting cannot take in place, each as a subquery leaf.

The rewriting handles one set operation per query level: a tree of UNION ALL nodes (the ⊎ of its leaves), or a single EXCEPT over two leaves; a non-ALL top node is first wrapped by rewrite_non_all_into_external_group_by. Anything else below the top node would be mistreated: a UNION under a UNION ALL would lose its deduplication, an EXCEPT there is another operation altogether, and so is any set operation below an EXCEPT. Each such subtree becomes a query of its own, which the recursion into subqueries then rewrites at its own level; this is the rewriting a user would do by hand by moving the inner set operation to a FROM subquery.

Runs on a query whose top set operation is already ALL. The range table is rebuilt, so that it holds exactly the remaining leaves, the leftmost first.

Returns
true if anything was nested.

Definition at line 12171 of file provsql.c.

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

◆ nested_agg_trackable()

bool nested_agg_trackable ( const constants_t * constants,
Query * q,
Aggref * agg )
static

Whether the aggregate agg of an aggregate result of another kind can be tracked per possible world.

The contribution of each row is then semimod(g, k) with g the inner aggregate's own gate (provenance_semimod_nested), so the value of the outer aggregate is read in every world rather than frozen on the database as it is. Only an evaluator that reads a value per world resolves such a gate, so the shape is kept narrow: one plain agg_token argument, an outer aggregate the samplers compute, and a numeric inner value.

Definition at line 818 of file provsql.c.

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

◆ nested_limit_on_provenance()

bool nested_limit_on_provenance ( const constants_t * constants,
Query * q,
bool top )
static

Whether a LIMIT / OFFSET that stays a truncation applies to a provenance-tracked query below the top level of q.

A LIMIT that is the filter of a rank (limit_lowerable) is tracked. The others – LIMIT plain(k), a LIMIT without ORDER BY, over an aggregation... – truncate the result as computed on the actual data, and the rows kept carry the tokens they have in the full result: that they were among the rows kept, which depends on the rows before them, is not recorded. At the top level, the statement displays some rows of the full result, each correctly annotated. Below it – in a FROM or LATERAL subquery, a CTE, an arm of a set operation – the truncated result feeds further computation, whose annotations then miss that dependence. Sublink bodies are not examined: a LIMIT there is either lowered or rejected by the sublink rewrites.

Parameters
constantsExtension OID cache.
qQuery to inspect, with the queries nested in its range table and its WITH clause.
topTrue for the statement's own query, whose LIMIT is not reported.
Returns
True if there is such a LIMIT / OFFSET.

Definition at line 29081 of file provsql.c.

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

◆ node_is_agg_token()

bool node_is_agg_token ( Node * n,
const constants_t * constants )
static

Definition at line 7235 of file provsql.c.

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

◆ node_varies_walker()

bool node_varies_walker ( Node * n,
void * ctx )
static

Does n hold a Var, an aggregate or a subquery – anything that is not the same in every row and every world?

Definition at line 22740 of file provsql.c.

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

◆ normalize_agg_comparison()

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

Fold constant arithmetic over an aggregate into the comparison threshold.

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

Definition at line 4819 of file provsql.c.

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

◆ normalize_bool_agg_having()

Node * normalize_bool_agg_having ( Node * n)
static

Definition at line 14257 of file provsql.c.

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

◆ normalize_distinct_into_group_by()

void normalize_distinct_into_group_by ( Query * q)
static

Normalise a supported SELECT DISTINCT into a GROUP BY.

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

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

Parameters
qQuery to normalise in place.

Definition at line 11609 of file provsql.c.

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

◆ normalize_inner_joins()

void normalize_inner_joins ( Query * q)
static

Canonicalise explicit inner joins in q's FROM to the comma-join form: each all-inner JoinExpr fromlist item becomes its leaf RangeTblRefs, the ON conditions are splayed into one flat WHERE conjunction, every reference to the dissolved joins' alias columns (USING / NATURAL merged columns included) is resolved to base expressions, and the dissolved RTE_JOIN entries are dropped from the range table with every surviving rtindex renumbered.

A fromlist item containing an outer join is kept intact for lower_outer_joins, as is the whole query when a whole-row Var references a dissolved join (unresolvable through joinaliasvars). Runs on every tracked query level and – via normalize_inner_joins_walker – on every nested Query (sublink bodies, subquery RTEs, CTE bodies), before any shape-sensitive pass.

Definition at line 24883 of file provsql.c.

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

◆ normalize_inner_joins_walker()

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

Walker: apply normalize_inner_joins to every nested Query – sublink subselects, subquery RTEs, CTE bodies – so that e.g.

a sublink body is already canonical when the sublink pre-passes inspect it.

Definition at line 26223 of file provsql.c.

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

◆ normalize_outer_join_tree()

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

Bring the outer joins of q to the shape lower_outer_joins lowers: one outer join of two range-table entries as the whole FROM.

An arm of an outer join that is itself a join, and an outer join beside other FROM items, are moved into a subquery (wrap_join_tree), which the processing of the subquery then lowers, normalizing it again if needed: (a LEFT JOIN b) LEFT JOIN c reads (SELECT ... FROM a LEFT JOIN b) LEFT JOIN c. Not with a LATERAL entry (which could read the moved relations).

Returns
true if q was changed.

Definition at line 15654 of file provsql.c.

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

◆ normalize_quantified_aggregate_sublinks()

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

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

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

Definition at line 17092 of file provsql.c.

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

◆ nullif_agg_to_case()

CaseExpr * nullif_agg_to_case ( NullIfExpr * ni,
const constants_t * constants )
static

NULLIF over an aggregate as the searched CASE it means.

NULLIF(a,b) is NULL where a = b and a otherwise, so

CASE WHEN a = b THEN NULL ELSE a END

says it, including where a is NULL: the equality is then unknown, the ELSE gives a back, and NULL is what NULLIF answers there too. The guard is a comparison between an aggregate and a value of the row, which having_Expr_to_provenance_cmp reads as it does the guards of a CASE the query wrote itself.

The compared value has to hold no aggregate of its own, as a COALESCE default does not (coalesce_agg_to_case): it is lifted into a value gate, so what it needs is to be the same in every world.

Definition at line 7558 of file provsql.c.

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

◆ oj_body_has_tracked_relation()

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

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

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

Definition at line 17064 of file provsql.c.

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

◆ oj_build_antijoin()

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

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

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

Definition at line 15003 of file provsql.c.

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

◆ oj_build_coltype_lists()

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

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

Definition at line 15051 of file provsql.c.

Here is the caller graph for this function:

◆ oj_build_diff()

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

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

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

Definition at line 14942 of file provsql.c.

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

◆ oj_build_join_query()

Query * oj_build_join_query ( const constants_t * constants,
Query * outer,
RangeTblEntry * R,
RangeTblEntry * S,
Index R_idx,
Index S_idx,
oj_cols * Rc,
oj_cols * Sc,
Node * theta,
bool select_r,
bool select_s,
int depth )
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 14820 of file provsql.c.

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

◆ oj_build_rel_query()

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

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

Definition at line 14908 of file provsql.c.

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

◆ oj_build_uncorrelated_from_subquery()

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

Definition at line 18527 of file provsql.c.

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

◆ oj_build_union()

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

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

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

Definition at line 15074 of file provsql.c.

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

◆ oj_collect_cols()

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

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

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

Definition at line 14599 of file provsql.c.

Here is the caller graph for this function:

◆ oj_contains_sublink_walker()

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

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

Definition at line 16078 of file provsql.c.

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

◆ oj_copy_rel()

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

Copy an outer-join arm RTE into the range table of subquery sub, depth levels below outer.

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

Definition at line 14723 of file provsql.c.

Here is the caller graph for this function:

◆ oj_count_cmp()

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

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

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

Definition at line 16115 of file provsql.c.

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

◆ oj_count_const_cmp()

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

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

Definition at line 18838 of file provsql.c.

Here is the caller graph for this function:

◆ oj_count_distinct_cmp()

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

Definition at line 16171 of file provsql.c.

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

◆ oj_decorr_var_mut()

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

Definition at line 15994 of file provsql.c.

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

◆ oj_having_gated_subquery()

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

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

Definition at line 18682 of file provsql.c.

Here is the caller graph for this function:

◆ oj_is_arith_opexpr()

bool oj_is_arith_opexpr ( Node * node)
static

Is node a binary/unary +,-,*,/,^,@ operator expression?

Mirrors the predicate in try_swap_agg_arith: exactly the arithmetic operators whose agg_token overloads build a gate_arith token that carries provenance through the operation. Used to decide whether a scalar sublink nested inside a target-list expression sits in provenance-carrying arithmetic (so it can be lifted to choose()) or in something opaque (a function call, CASE …) that cannot propagate provenance.

Definition at line 19485 of file provsql.c.

Here is the caller graph for this function:

◆ oj_joinref_walker()

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

Definition at line 15151 of file provsql.c.

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

◆ oj_jointree_rtindexes()

void oj_jointree_rtindexes ( Node * jtnode,
Bitmapset ** idx )
static

Collect into idx the range-table indexes jtnode reads.

Definition at line 15561 of file provsql.c.

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

◆ oj_lateral_reads_join()

bool oj_lateral_reads_join ( RangeTblEntry * r,
Bitmapset * idx )
static

Whether the LATERAL entry r reads a row of idx, the entries of the outer join that lower_outer_joins moves into a subquery.

Such a LATERAL cannot follow the join there – its reference would have to reach inside that subquery – whereas one that reads nothing of the join (a LATERAL over constants, or over another item of the same FROM) is no obstacle and stays where it is.

Definition at line 15617 of file provsql.c.

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

◆ oj_limit_count_is_one()

bool oj_limit_count_is_one ( Node * limitCount)
static

Is limitCount the literal 1?

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

Definition at line 19405 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_aggref()

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

Build an Aggref for a single-argument aggregate.

Definition at line 16087 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_count_distinct()

Aggref * oj_make_count_distinct ( Expr * valexpr)
static

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

Build "count(DISTINCT v)" over valexpr.

Definition at line 16145 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_count_star()

Aggref * oj_make_count_star ( void )
static

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

Definition at line 18662 of file provsql.c.

Here is the caller graph for this function:

◆ oj_make_subquery_rte()

RangeTblEntry * oj_make_subquery_rte ( Query * sub)
static

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

Definition at line 14693 of file provsql.c.

Here is the caller graph for this function:

◆ oj_neutralize_orphan_arm()

void oj_neutralize_orphan_arm ( RangeTblEntry * rel)
static

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

Definition at line 14755 of file provsql.c.

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

◆ oj_outer_remap()

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

Definition at line 15187 of file provsql.c.

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

◆ oj_param_repl_mut()

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

Replace every PARAM_SUBLINK with paramid by replacement.

Definition at line 17048 of file provsql.c.

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

◆ oj_reads_rtindexes_walker()

bool oj_reads_rtindexes_walker ( Node * node,
oj_reads_ctx * ctx )
static

Walker: a Var of level sublevels_up reading one of idx.

Definition at line 15586 of file provsql.c.

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

◆ oj_refs_join_index()

bool oj_refs_join_index ( Query * q,
Index join_idx )
static

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

Definition at line 15165 of file provsql.c.

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

◆ oj_renum_mut()

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

Definition at line 14786 of file provsql.c.

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

◆ oj_replace_sublink_mut()

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

Replace one specific SubLink node with repl, in place.

Used to lift a sublink nested in target-list arithmetic to its choose() aggregate without disturbing the surrounding operators, so the arithmetic survives and carries the lifted token's provenance.

Definition at line 19667 of file provsql.c.

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

◆ oj_rtables_coalescible()

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

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

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

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

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

Definition at line 19445 of file provsql.c.

Here is the caller graph for this function:

◆ oj_rte_has_provsql()

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

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

Definition at line 14659 of file provsql.c.

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

◆ oj_sl_replace_mut()

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

Definition at line 16068 of file provsql.c.

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

◆ oj_sub_bodies_coalescible()

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

Definition at line 19463 of file provsql.c.

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

◆ oj_sublink_scan_walker()

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

Definition at line 16038 of file provsql.c.

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

◆ oj_syscol_walker()

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

Walker: does any Var read a whole row (varattno 0) or a system column (varattno < 0, ctid, xmin, ...) of either arm of the outer join being lowered?

The lowering puts each arm in a subquery, and a subquery has neither: a system column locates a physical row, which the rows of a subquery do not have, and the relation's own row type is not the subquery's. A whole-row value the rewriting reads as an anonymous record is already gone by here (hide_provsql_in_wholerows runs first), so one still present is one that pass left because the relation's own row type is needed – which the lowering cannot give either.

Left in place, such a Var keeps a varno the lowering retargets and an attribute number the new entry has no column for, and what came out was not a refusal but a broken tree: "attribute 24 of relation (null) does not exist", "type tid is not composite", "ROW() column has type integer instead of type text", and – for count(DISTINCT p.ctid) over two outer joins – a segfault in the planner, writing past attr_needed of the wrong relation.

Definition at line 15782 of file provsql.c.

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

◆ oj_tl_sublink_in_arith()

bool oj_tl_sublink_in_arith ( Node * node,
SubLink * sl )
static

Is SubLink sl reachable from node through arithmetic only?

True iff sl is nested inside node through a chain of nothing but arithmetic OpExprs (oj_is_arith_opexpr) and casts. Cast peeling uses peel_agg_casts – the same RelabelType / 1-arg cast FuncExpr set the downstream try_swap_agg_arith peels – so detection and execution agree (e.g. an int sublink divided by a numeric: the implicit cast is peeled here and again when the agg_token operator is resolved). Such a sublink can be lifted to a choose() aggregate in place: the surrounding +,-,*,/ then carry the subquery's provenance via gate_arith. Any other enclosing node returns false, leaving the sublink to the warning passthrough (its provenance genuinely cannot flow through, e.g. a non-cast function argument).

Definition at line 19532 of file provsql.c.

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

◆ oj_uncorrelated_body_over_tracked()

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

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

The targetList is not inspected (callers replace it).

Definition at line 18635 of file provsql.c.

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

◆ oj_wrap_body_from()

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

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

Mirror of oj_wrap_outer_from, but for the SubLink body: every body relation must be a base relation, at least one of them tracked, and the FROM a comma-join (JOIN-syntax bodies arrive already canonicalised to that form by normalize_inner_joins). 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 of its tracked relations (an untracked relation contributes the neutral 1).

Definition at line 18353 of file provsql.c.

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

◆ oj_wrap_body_with_match_ind()

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

Wrap a NULL-guarded antijoin body into a derived subquery D carrying a constant match-indicator column.

Under the 3VL guards of extract_quantified_corr a corr-matched Q row can be NULL in every data column, so after decorrelation no data column can key the matched / null-padded distinction that the count(*) -> count(Q.key) rewrite needs. The indicator is a constant TRUE projected by D: non-NULL on every genuine row, NULL on the padded antijoin row like any other D column. The aggstar arm of decorrelate_scalar_sublinks prefers it as the count key.

Definition at line 18456 of file provsql.c.

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

◆ oj_wrap_outer_from()

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

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

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

Definition at line 16238 of file provsql.c.

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

◆ oj_wrap_remap_mut()

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

Definition at line 16201 of file provsql.c.

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

◆ oj_zero_satisfies()

bool oj_zero_satisfies ( Oid opno,
Const * c )
static

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

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

Definition at line 18854 of file provsql.c.

Here is the caller graph for this function:

◆ operator_name()

List * operator_name ( const char * op,
Oid ltype,
Oid rtype )
static

The name of operator op between types ltype and rtype (InvalidOid for a prefix operator's left side), for a lookup.

Qualified with the provsql schema when an operand has a type of it (agg_token, random_variable): its operators are there, and a session need not have the schema in its search_path.

Definition at line 4777 of file provsql.c.

Here is the caller graph for this function:

◆ or_exprs()

Expr * or_exprs ( Expr * a,
Expr * b )
static

"a OR b", either of which may be NULL (absent).

Definition at line 6202 of file provsql.c.

Here is the caller graph for this function:

◆ orig_agg_arg_of_column()

Oid orig_agg_arg_of_column ( Query * sub,
AttrNumber attno,
const constants_t * constants,
int depth,
int argno )
static

The aggregate function (argno 0) or the type (argno 1) of the aggregate an agg_token column of sub comes from, or InvalidOid.

Follows the column down: to the provenance_aggregate() call that makes it (its first two arguments are the aggregate and its type), through the subqueries that pass it on, and through the arms of a set operation (the padding of a lowered outer join is one).

Definition at line 21167 of file provsql.c.

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

◆ orig_agg_arg_of_var()

Oid orig_agg_arg_of_var ( Query * q,
Var * v,
const constants_t * constants,
int depth,
int argno )
static

orig_agg_arg_of_column for a Var of q, or InvalidOid.

Definition at line 21138 of file provsql.c.

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

◆ orig_agg_type_of_var()

Oid orig_agg_type_of_var ( Query * q,
Var * v,
const constants_t * constants,
int depth )
static

The type of the aggregate an agg_token Var of q comes from (orig_agg_arg_of_column), or InvalidOid.

Definition at line 21152 of file provsql.c.

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

◆ outer_refs_are_keys_walker()

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

Walker: every Var of the query depth levels up is one of its grouping expressions, and no aggregate of that query is read.

Definition at line 25218 of file provsql.c.

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

◆ output_provably_not_null()

bool output_provably_not_null ( const Query * sub,
AttrNumber attno )
static

Whether output column attno of subquery sub can never be NULL.

Conservative: sub is a plain SELECT (no set operation, no grouping sets) whose FROM is a list of relations and subqueries without any join node, so that no outer join can pad the column, and the column is a constant, a column declared NOT NULL, or such a column of a nested subquery of the same kind.

Definition at line 17211 of file provsql.c.

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

◆ param_takes_any_row()

bool param_takes_any_row ( Oid funcid,
int i )
static

Whether argument i of funcid takes any row: a parameter of type record, "any", or a polymorphic one of a function whose result type does not follow it (row_to_json, to_jsonb, json_agg...).

Definition at line 26379 of file provsql.c.

Here is the caller graph for this function:

◆ partition_only_winref()

Index partition_only_winref ( Query * q,
WindowClause * wc )
static

The window with the partition of wc and no ordering, creating it where the query has none: what cume_dist divides by.

Definition at line 26785 of file provsql.c.

Here is the caller graph for this function:

◆ peel_agg_casts()

Node * peel_agg_casts ( Node * n)
static

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

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

Definition at line 10168 of file provsql.c.

Here is the caller graph for this function:

◆ peel_agg_token_arm()

Node * peel_agg_token_arm ( Node * n,
const constants_t * constants )
static

GREATEST / LEAST of two arguments as the searched CASE it means.

GREATEST(a,b) is the larger of the two values, and SQL reads a NULL argument as no value rather than as an unknown: GREATEST(NULL,5) is 5. The CASE that says so is

CASE WHEN a IS NULL THEN b WHEN b IS NULL THEN a
WHEN a > b THEN a ELSE b END

("<" for LEAST), whose guards are the readings having_Expr_to_provenance_cmp already builds: an IS NULL on an aggregate, a comparison between two of them, and the indicator of a regular condition where an argument is not an aggregate. The two NULL guards are what a plain "CASE @c WHEN @c a @c > @c b" would get wrong, its unknown comparison falling to the ELSE.

Two arguments, and an aggregate one has to be a kind whose NULL-ness has a reading (count, sum, avg, min, max, choose); anything else is left to be read as a plain value.

n with the casts around an agg_token peeled off, or n itself where no agg_token is under them (a constant arm keeps the coercions the query gave it).

Definition at line 7628 of file provsql.c.

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

◆ peel_widening_agg_cast()

Node * peel_widening_agg_cast ( Node * n,
const constants_t * constants )
static

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

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

The aggregate result under a widening numeric cast, or NULL.

CAST(count(*) AS real) reads the count as a number and widens it: the aggregate is under two casts, the one ProvSQL inserts to read its value and the one the query writes. Since the agg_token arithmetic computes in numeric, which every such widening subsumes, the operand is taken as the aggregate itself and the operation is carried by a gate.

Only a widening is peeled – to numeric without a typmod, to real or to double precision. A cast that rounds or truncates (CAST(avg(x) AS int), CAST(sum(x) AS numeric(10,2))) is part of what the query computes and is left where it is.

Definition at line 10223 of file provsql.c.

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

◆ pending_agg_case_walker()

bool pending_agg_case_walker ( Node * n,
void * cx )
static

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

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

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

Walker: a conditional over an aggregate – a CASE, COALESCE, NULLIF, GREATEST or LEAST – which rewrite_agg_cases lowers to an agg_case after cast_agg_token_mutator has run.

Definition at line 10638 of file provsql.c.

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

◆ place_star_provsql_last()

void place_star_provsql_last ( Query * q,
const char * src )
static

Put the provsql column that * expands to at the end of the target list of q, as the rewriting shows it.

* brings the provsql column of a table in the middle of the columns, while the result of the rewriting has the row's provenance last: a column list of a view over SELECT *, or a position in ORDER BY, then points at other columns than the user sees. The first such column goes last, those of other stars (a join) are dropped, as the rewriting would drop them; positional ORDER BY keys follow. Only the provsql column of a table or view is concerned; an explicit provsql is left in place.

Definition at line 30320 of file provsql.c.

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

◆ plain_agg_value()

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

The value of the agg_token arg as a target_type, read where the query ASKED for the plain value with plain().

The same value as frozen_agg_value, through agg_token_plain_text rather than agg_token_frozen_value. Neither warns at execution; what differs is that the statement's report of its frozen values looks for the latter (frozen_agg_value_walker), so a read the user asked for is not reported back to them – which is what "mark it plain() to say so" says will happen. NULL on a schema without the function.

Definition at line 560 of file provsql.c.

Here is the caller graph for this function:

◆ plain_row_token()

Expr * plain_row_token ( const constants_t * constants,
Query * q,
List * prov_atts,
semiring_operation op )
static

Definition at line 9940 of file provsql.c.

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

◆ predicate_subselect_decorrelatable()

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

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

Requires a body FROM over base relations, at least one of them tracked – a single relation Q, or a comma-join that oj_wrap_body_from collapses downstream into one derived cross-product subquery (untracked relations ride along in the derived subquery, contributing the neutral provenance they would in any join) – 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. Bodies arrive here already canonicalised to the comma-join form by normalize_inner_joins (a body it declined – an outer join, a whole-row join reference – fails the fromlist check).

Definition at line 16934 of file provsql.c.

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

◆ predicate_to_condition_gate()

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

Convert a Boolean predicate into a provenance condition gate.

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

Definition at line 6838 of file provsql.c.

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

◆ process_inert_fetches()

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

Definition at line 24633 of file provsql.c.

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

◆ process_inert_fetches_walker()

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

Definition at line 24602 of file provsql.c.

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

◆ process_insert_select()

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

Propagate provenance through INSERT ... SELECT.

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

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

Definition at line 28730 of file provsql.c.

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

◆ process_query()

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

Definition at line 27759 of file provsql.c.

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

◆ process_set_operation_union()

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

Recursively annotate a UNION tree with the provenance UUID type.

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

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

Definition at line 20630 of file provsql.c.

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

◆ provenance_function_in_group_by()

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

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

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

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

Definition at line 12418 of file provsql.c.

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

◆ provenance_function_walker()

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

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

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

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

Definition at line 12393 of file provsql.c.

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

◆ provenance_in_sublink_walker()

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

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

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

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

Definition at line 13266 of file provsql.c.

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

◆ provenance_mutator()

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

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

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

Definition at line 11489 of file provsql.c.

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

◆ provsql_ctas_kind_label()

const char * provsql_ctas_kind_label ( provsql_table_kind k)
static

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

Definition at line 29867 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_executor_end()

void provsql_executor_end ( QueryDesc * queryDesc)
static

Definition at line 29661 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_executor_start()

void provsql_executor_start ( QueryDesc * queryDesc,
int eflags )
static

Definition at line 29642 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_planner()

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

PostgreSQL planner hook – entry point for provenance rewriting.

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

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

Definition at line 29326 of file provsql.c.

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

◆ provsql_post_parse_analyze()

void provsql_post_parse_analyze ( ParseState * pstate,
Query * query )
static

Post-parse-analysis hook: see place_star_provsql_last.

Runs on the SELECT of a statement and on that of a CREATE VIEW (analysed on its own by DefineView), before the planner hook.

Definition at line 30447 of file provsql.c.

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

◆ provsql_ProcessUtility()

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

Definition at line 30063 of file provsql.c.

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

◆ provsql_ProcessUtility_apply()

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

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

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

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

Definition at line 29894 of file provsql.c.

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

◆ provsql_ProcessUtility_capture()

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

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

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

Definition at line 29751 of file provsql.c.

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

◆ provsql_provenance_assign_hook()

void provsql_provenance_assign_hook ( int newval,
void * extra )
static

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

Definition at line 161 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_subxact_callback()

void provsql_subxact_callback ( SubXactEvent event,
SubTransactionId mySubid,
SubTransactionId parentSubid,
void * arg )
static

Subtransaction callback: an aborted subtransaction (a PL/pgSQL exception block) leaves the executor depth it started at.

Definition at line 252 of file provsql.c.

Here is the caller graph for this function:

◆ provsql_xact_callback()

void provsql_xact_callback ( XactEvent event,
void * arg )
static

Transaction callback: no executor runs between transactions.

ExecutorEnd is not called for a statement that fails while it runs, so the counting of provsql_executor_start / provsql_executor_end is off after an error; the end of the transaction sets it back.

Definition at line 244 of file provsql.c.

Here is the caller graph for this function:

◆ pull_aggregates_mutator()

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

Mutator: an aggregate or a column of this level becomes a reference to the column of ctx->inner exposing it.

Definition at line 26701 of file provsql.c.

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

◆ pull_up_vars_deep_mutator()

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

Mutator: pull_up_vars_mutator, also for the Vars of the query that nested queries (subquery expressions) read from one or more levels down.

Definition at line 16424 of file provsql.c.

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

◆ pull_up_vars_mutator()

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

Mutator: replace each Var of level 0 by a reference to an entry of ctx->inner exposing it, appended if needed.

Definition at line 16382 of file provsql.c.

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

◆ push_agg_nulltest_into_subquery()

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

Push IS [NOT] NULL on a subquery's aggregate down into that subquery's HAVING.

The HAVING lowering of IS [NOT] NULL is built from the aggregate's per-row (value, token) pairs, which live in the provenance_aggregate call itself – so, unlike a comparison (lowered to a gate_cmp over the finished gate_agg, and therefore computable from the token alone), it can only be built in the query level that owns the aggregate. Moving the predicate to that level is what lets WHERE c IS NULL over a grouped subquery mean what the fused HAVING sum(v) IS NULL means. Filtering the subquery's rows is also the predicate's ordinary SQL reading, so the data part is unchanged.

Runs before provenance discovery, so the subquery is rewritten with the HAVING already in place.

Parameters
qQuery to rewrite (modified in place).
constantsExtension OID cache.
Returns
q when something moved, NULL when nothing matched.

Definition at line 21973 of file provsql.c.

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

◆ push_arith_into_agg_mutator()

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

Tree-mutator applying try_push_into_aggref bottom-up.

Definition at line 10891 of file provsql.c.

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

◆ push_one_agg_nulltest()

bool push_one_agg_nulltest ( NullTest * nt,
agg_nulltest_ctx * ctx )
static

Move one IS [NOT] NULL conjunct into its subquery's HAVING.

Returns
True when nt tested a subquery's aggregate and was moved.

Definition at line 21936 of file provsql.c.

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

◆ query_defines_handmade_provsql()

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

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

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

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

Definition at line 28908 of file provsql.c.

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

◆ query_has_inert_fetch()

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

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

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

Definition at line 12622 of file provsql.c.

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

◆ query_has_own_sublinks()

bool query_has_own_sublinks ( Query * q)
static

Whether a subquery expression remains in q's own clauses (its target list, conditions or HAVING): what hasSubLinks must say after a rewriting removed some, since the planner plans the subquery expressions only of a query that says it has some.

Definition at line 14008 of file provsql.c.

Here is the caller graph for this function:

◆ query_has_tracked_sublink()

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

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

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

Definition at line 12874 of file provsql.c.

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

◆ query_is_scalar_aggregation()

bool query_is_scalar_aggregation ( const Query * cq)
static

Whether cq is one row in every possible world: a bare aggregate, which is defined over no row as well as over some.

Definition at line 18520 of file provsql.c.

Here is the caller graph for this function:

◆ query_references_cte()

bool query_references_cte ( Query * q,
const char * name )
static

Does q (at any depth) reference a CTE named name?

Definition at line 2506 of file provsql.c.

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

◆ rank_key_before()

Node * rank_key_before ( rank_window_ctx * ctx,
SortGroupClause * k )
static

"b.k ≺ a.k" – the row the counting subquery reads comes strictly before the one ranked, on the key k alone.

A key that reads an aggregate is compared by the ordering operator, which is the comparison of two aggregate results that the correlated-subquery rewriting tracks; a NULL aggregate satisfies no comparison, as the evaluators read it everywhere else. A key of the data carries the NULLS FIRST / LAST the query asked for, which the bare operator does not say (a comparison with NULL is unknown, so neither row would come before the other).

Definition at line 27144 of file provsql.c.

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

◆ rank_key_is_aggregate()

bool rank_key_is_aggregate ( rank_window_ctx * ctx,
SortGroupClause * k )
static

Whether the key k of a rank reads an aggregate result, which is compared per possible world, rather than a value of the data.

Definition at line 27123 of file provsql.c.

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

◆ rank_key_same()

Node * rank_key_same ( rank_window_ctx * ctx,
SortGroupClause * k )
static

"b.k = a.k" – the two rows tie on the key k, so the next key decides.

Two NULLs of the data tie, as they do for GROUP BY.

Definition at line 27171 of file provsql.c.

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

◆ rank_key_vars()

void rank_key_vars ( rank_window_ctx * ctx,
SortGroupClause * k,
Var ** inner,
Var ** outer )
static

The two readings of a sort key of a rank: b.k inside the subquery that counts, and a.k of the row ranked, one level up.

Definition at line 27111 of file provsql.c.

Here is the caller graph for this function:

◆ rank_order_is_total()

bool rank_order_is_total ( rank_window_ctx * ctx,
WindowFunc * wf )
static

Whether the order of the rank window wf tells every two rows of the relation ranked apart, so that no two of them tie.

True where the ordering keys hold every column that identifies a row (the grouping columns of an aggregation): two distinct rows differ on one of them, so they differ on a key. A row_number() is then the rank() it is tracked as, and the warning that they may differ has nothing to warn about – which is the common case once a top-k breaks the ties of its count on a date or an id.

Definition at line 27596 of file provsql.c.

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

◆ reads_agg_value_walker()

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

Walker: does the expression read the value of an aggregate?

An aggregate of the block itself, a column of a FROM subquery that is one, or a scalar subquery that aggregates: the three shapes a sort key takes when it orders by "how many" rather than by a value of the data. The wider reading is the one the fragment uses, and the one the top-k of an aggregation needs: the key of "ORDER @c BY @c (SELECT @c count(*) @c ...) @c DESC @c LIMIT @c 10" is an aggregate value as much as "ORDER @c BY @c count(*)" is.

Definition at line 29199 of file provsql.c.

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

◆ reads_outside_walker()

bool reads_outside_walker ( Node * node,
Index depth )
static

Why a tracked sublink of q could not be rewritten.

Whether node reads a query above its own level, which is depth: 0 for an expression, the query for a Query being one level below itself (so that a Query argument starts at its own level).

The refusal used to name the constructs rather than the obstacle ("Subqueries @c (EXISTS, @c IN, @c scalar @c subquery) @c not @c supported"), which says nothing about what to change – and says it of a query whose neighbours, of the same construct, are tracked. The shape of the body, of the block around it, and their number are what decide, so they are what the message names. The order of the tests is the order in which the rewrites give up.

Parameters
constantsExtension OID cache.
qThe block holding the sublink.
slThe sublink the rewrites left behind, or NULL.
Returns
A phrase to read after "not supported here:".

Definition at line 16481 of file provsql.c.

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

◆ reads_outside_walker_rec()

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

Walker: a reference (a Var, a CTE) to a query above the one the walk started in, depth levels up counting from there.

Definition at line 16454 of file provsql.c.

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

◆ reads_provenance_walker()

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

Walker: whether an expression calls provenance().

Definition at line 25057 of file provsql.c.

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

◆ reads_provsql_walker()

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

Walker: does any expression read a provsql column?

Reading the provenance column is a fetch of a token, not a read of data ("SELECT @c count(*) @c FROM @c t @c WHERE @c provsql @c IS @c NOT @c NULL" is a diagnostic), and ProvSQL leaves such a subquery to plain SQL rather than rewriting it. The lift honours that.

Definition at line 28946 of file provsql.c.

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

◆ reads_subquery_aggregate_walker()

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

Walker: a Var of this level reading a column that is an aggregate of a FROM subquery.

Definition at line 22567 of file provsql.c.

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

◆ reads_token_walker()

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

Walker: a provsql column or a provenance() call.

Definition at line 13289 of file provsql.c.

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

◆ reaggregates_agg_result()

bool reaggregates_agg_result ( const constants_t * constants,
Query * q,
Aggref * agg )
static

Whether the aggregate agg of query q reads an aggregate result of a subquery that it aggregates again as the rows of their groups.

sum over a sum or a count, max over a max, min over a min: the outer aggregate of a group of rows is that of the rows of their groups (provenance_semimod_flat); and count over a count, which is never NULL, counts the groups. A single argument, a column of the subquery, without DISTINCT, ORDER BY or FILTER.

Definition at line 777 of file provsql.c.

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

◆ reconcile_union_columns()

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

Give each column of a UNION one type across its arms, once their aggregates have become agg_token.

A column whose arms are all aggregates or NULL (the padding of a lowered outer join) is an agg_token, its NULL arms typed so. A column where an aggregate meets a plain value (UNION ALL of a count and a constant) reads the aggregates as values, the plain value having no provenance to join. The types are set on every node of the tree, and on the query's own Vars of the column, which the set operation reads from its first arm.

Definition at line 20554 of file provsql.c.

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

◆ recount_cte_refs_walker()

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

Walker: set the reference count of every CTE to the number of its references in the rewritten query.

The rewriting copies subqueries (the arms of a lowered outer join, ...), and with them their references to the CTEs kept as CTEs. PostgreSQL inlines a CTE referenced once, into the one reference it finds; the other copies would then refer to a CTE that has no plan.

Definition at line 13956 of file provsql.c.

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

◆ reduce_varattno_by_offset()

void reduce_varattno_by_offset ( Query * q,
Index varno,
int * offset )
static

Adjust Var attribute numbers in q 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 of q: in its target list and conditions, where a comparison on a column after the removed one would otherwise read the wrong column, and in the queries nested in it (a LATERAL subquery, a function of the FROM list, a subquery expression), which reach it from further down.

Parameters
qOuter query to patch.
varnoRange-table entry whose attribute numbers need fixing.
offsetCumulative shift per original attribute (negative or zero).

Definition at line 491 of file provsql.c.

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

◆ reduce_varattno_walker()

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

Tree-walker callback that adjusts Var attribute numbers, in place.

Parameters
nodeCurrent expression tree node.
ctxPointer to a reduce_varattno_context.
Returns
Always false (walk everything).

Definition at line 449 of file provsql.c.

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

◆ refuse_agg_token_group_key()

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

Refuse a GROUP BY / DISTINCT key that is an expression over the value of a subquery's aggregate.

The explosion (agg_value_read_as_data) reads the values of an aggregate COLUMN, and of a cast of one; an expression over it – floor(ln(cnt)), cnt * 2 – takes values of its own, which are not among the contributions the aggregate reads, so there is nothing to enumerate. Left alone the key keeps its agg_token once the aggregate is lowered, and PostgreSQL then groups by the token: one group per row, silently, where the answer has one group for all the rows whose value agrees. Refused rather than answered wrongly; the aggregate itself, or a cast of it, can be grouped.

Definition at line 22602 of file provsql.c.

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

◆ refuse_except_all()

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

Raise the error except_all_on_provenance_walker calls for.

Definition at line 29146 of file provsql.c.

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

◆ refuse_tracked_group_key()

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

Refuse a grouping key that is STILL an agg_token once every rewriting has run.

refuse_agg_token_group_key catches an expression over a subquery's AGGREGATE early, by asking what the subquery's column is. It cannot catch an expression over a tracked window RANK – "index / 1000" over a row_number() – because at that point the column is a WindowFunc, not an aggregate and not yet an agg_token, so nothing identifies it. Here the arithmetic has been swapped onto the agg_token operators, so the key's own type answers the question: a key that is an agg_token groups by one token per row, and returns one group per row where SQL returns one group for every row whose value agrees – silently, a wrong GROUPING rather than a wrong value, which nothing checking values would catch.

A key read to a plain type – plain(...), which the refusals name – is not an agg_token by here and is not caught; neither is an exploded key, whose rows carry the value rather than the token.

Definition at line 26538 of file provsql.c.

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

◆ remap_positional_sort()

void remap_positional_sort ( Query * q,
const char * src,
List * resolved,
List * shown )
static

Point the positional ORDER BY keys of q at the columns in the order the result shows them.

resolved is the order in which parse analysis counted the columns, shown the order of the result, provsql last. A key k resolved to resolved[k] now sorts on shown[k], with the operators of its type.

Definition at line 30231 of file provsql.c.

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

◆ remove_provenance_attribute_groupref()

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

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

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

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

Definition at line 11661 of file provsql.c.

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

◆ remove_provenance_attribute_setoperations()

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

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

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

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

Definition at line 11698 of file provsql.c.

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

◆ remove_provenance_attributes_select()

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

Strip provenance UUID columns from q's SELECT list.

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

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

Definition at line 3637 of file provsql.c.

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

◆ remove_provsql_from_select()

void remove_provsql_from_select ( Query * q)
static

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

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

Definition at line 14050 of file provsql.c.

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

◆ renumber_rte_mut()

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

Mutator: renumber every Var / RangeTblRef / JoinExpr rtindex of the compacted level through old_to_new, at any nesting depth (a nested subquery reaches the level via varlevelsup).

A varnosyn pointing at a dropped slot is cleared (the deparse hint has no surviving target).

Definition at line 24800 of file provsql.c.

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

◆ replace_aggregations_by_provenance_aggregate()

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

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

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

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

Definition at line 10917 of file provsql.c.

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

◆ replace_having_distinct_mutator()

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

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

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

Definition at line 9368 of file provsql.c.

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

◆ replace_provenance_function_by_expression()

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

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

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

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

Definition at line 11544 of file provsql.c.

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

◆ replace_rank_window_mutator()

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

Mutator: each rank window over the key of ctx becomes the subquery counting the rows before the current one.

Definition at line 27626 of file provsql.c.

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

◆ replace_window_aggregations()

bool replace_window_aggregations ( const constants_t * constants,
Query * q,
List * prov_atts )
static

Definition at line 11347 of file provsql.c.

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

◆ report_freeze()

void report_freeze ( const constants_t * constants,
Node * frozen,
const char * scope,
const char * tag,
const char * msg,
const char * hint )
static

Definition at line 13685 of file provsql.c.

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

◆ reset_varnoold_walker()

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

Walker: reset varnoold / varoattno of every Var to its varno / varattno.

The rewriting moves Vars between range tables, setting varno and varattno only. Before PostgreSQL 13, equal() also compares these two fields, kept for debugging: the planner then fails to match a moved Var with a copy of it (for instance "could not find pathkey item to sort" when sorting the input of a merge join).

Definition at line 13987 of file provsql.c.

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

◆ restore_insert_source_types()

void restore_insert_source_types ( Query * q,
Index src_rteid,
Query * subquery )
static

Coerce the rewritten source SELECT back to the types the INSERT expects.

The aggregate-provenance rewrite retypes an aggregate over a tracked relation to agg_token, but an INSERT's target row type was fixed by parse analysis long before the planner hook ran, so the two stages disagree and the executor rejects the row ("table row type and query-specified row type do not match"). The rewrite is still what we want – for a provenance-tracked target it is what fills the provsql column – so rather than suppressing it we cast each retyped output column back to its declared type through the assignment casts agg_token exposes (bigint, integer, numeric, double precision, text), which extract the aggregate's running value. The provenance the cast drops is exactly the provenance the target column cannot store.

A no-op whenever the rewrite left the column types alone, which is the common (non-aggregate) case. A column with no reachable cast is left as it is, so the executor's own error still surfaces.

Definition at line 28678 of file provsql.c.

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

◆ retype_agg_var_walker()

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

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

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

Definition at line 21741 of file provsql.c.

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

◆ retype_union_var_mutator()

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

Mutator: retype the Vars of one column of a set operation.

Definition at line 20525 of file provsql.c.

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

◆ rewrite_agg_case_mutator()

Node * rewrite_agg_case_mutator ( Node * node,
void * context )
static

Definition at line 7729 of file provsql.c.

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

◆ rewrite_agg_cases()

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

Definition at line 7832 of file provsql.c.

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

◆ rewrite_agg_distinct()

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

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

For a single DISTINCT aggregate, produces a subquery:

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

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

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

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

Definition at line 9568 of file provsql.c.

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

◆ rewrite_array_sublinks()

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

Rewrite a top-level ARRAY(SELECT Q.col FROM Q WHERE corr) target-list entry into the aggregate body (SELECT array_collect(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_collect over the group (array_agg, except that no rows give {}, not NULL), so mutating it into an EXPR_SUBLINK aggregate body lets the aggregate arm lower it to array_collect(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 18218 of file provsql.c.

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

◆ rewrite_cond_predicate_mutator()

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

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

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

Definition at line 6955 of file provsql.c.

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

◆ rewrite_cond_predicates()

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

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

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

Definition at line 7070 of file provsql.c.

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

◆ rewrite_cume_dist()

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

Rewrite the cume_dist() windows of q into ratios of counts, or return NULL leaving q alone.

Definition at line 26885 of file provsql.c.

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

◆ rewrite_deviation_aggregates()

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

Read every stddev / variance of q as the arithmetic over sum, sum of squares and count that defines it.

Run before the aggregates are lowered, so that what the provenance pass meets are the aggregates it carries. q->hasAggs stays true, and the CASE the guard makes is lowered by rewrite_agg_cases just after.

Definition at line 7820 of file provsql.c.

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

◆ rewrite_dml_rv_surface()

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

Lower the RV surface in the values a data-modifying statement supplies directly.

A single-row "INSERT ... VALUES (expr)" puts expr straight into the INSERT's own target list, a multi-row one into an RTE_VALUES, and an "UPDATE ... SET c = expr" into the UPDATE's target list; none of those positions is a SELECT, so process_query – and with it rewrite_probability_events – never sees them. A GREATEST / LEAST or a CASE over random_variable operands would then survive to execution and raise in the btree comparator, even though the identical expression one position over (in a SELECT list, or in the source of an "INSERT ... SELECT") is lifted into its order-statistic gate_arith. GREATEST / LEAST is SQL grammar rather than an overloadable function, so there is no way to reach the lifted form by writing the call differently. Apply the surface-lowering pass at all three positions.

The event-lifting second pass that rewrite_probability_events runs on a SELECT list is deliberately not applied here: it retypes a projected comparison from boolean to its uuid token, and a data-modifying statement's column types are already fixed by parse analysis. The lowerings applied are all type-preserving, so they cannot desync it the same way.

Definition at line 8058 of file provsql.c.

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

◆ rewrite_explode_agg_cmp_truth()

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

Explode the truth of a comparison of an aggregate against a constant into the two rows its two truths give.

Returns
The rewritten query, or NULL when no comparison of that shape is read as data here.

Definition at line 22917 of file provsql.c.

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

◆ rewrite_explode_agg_values()

Query * rewrite_explode_agg_values ( Query * q,
const constants_t * constants,
Index rteid,
List * cols )
static

The aggregate columns cols of the subquery at rteid, each exploded into one row per value its aggregate takes over the possible worlds.

Replaces the subquery R at rteid by

SELECT r.c_1, ..., v_1::T AS c_a1, ..., v_k::T AS c_ak, ..., r.c_n
FROM R r, LATERAL unnest(agg_possible_values(r.c_a1)) AS v_1,
..., LATERAL unnest(agg_possible_values(r.c_ak)) AS v_k
WHERE (v_1 IS NULL AND r.c_a1 IS NULL) OR r.c_a1 = v_1::T
AND ...

The columns keep their order and their types, so the level above is left as it is: what changes is that each aggregate column now holds a value of the database, one row per combination of values. The comparison in the WHERE is the one ProvSQL already gives a provenance to (having_OpExpr_to_provenance_cmp): the row of a value v is annotated [c = v] and keeps no cut of its own, so the rows of one group are pairwise exclusive and exactly one of them is in each world where the group is. Grouping, deduplicating or uniting on that column is then an operation on data, tracked as any other.

SEVERAL columns are exploded in ONE pass, and that is not a convenience: the decision of whether a column can take NULL, and the companion count(arg) that annotates the row where it does, are both read off the column's own Aggref. A pass that wrapped the arm first would leave the next column a plain Var of that wrapper, with no Aggref to read and nowhere to put a count – the wrapper aggregates nothing. Exploded one at a time, a two-aggregate arm therefore lost the row of the world where the arm holds no row at all: SUM(a), SUM(b) in a UNION arm gave every realised combination its right probability and dropped (NULL, NULL), whose mass (an eighth, on two rows at one half) no row carried. The combinations no world realises are emitted with a provenance of zero, which says of itself that no world holds it.

Parameters
qQuery to rewrite (modified in place).
constantsExtension OID cache.
rteid1-based varno of the subquery owning the aggregates.
colsThe columns to explode, at least one.
Returns
q, or NULL where the shape is not one this can rewrite.

Definition at line 23279 of file provsql.c.

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

◆ rewrite_explode_scalar_agg_cmp_truth()

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

Explode the truth of a comparison of an aggregate against a constant, read in the select list of a SCALAR aggregation, into one row per truth.

rewrite_explode_agg_cmp_truth makes the truth another grouping key, which a scalar aggregation cannot take: its row exists in every world, the one with no input row included (count(*) is 0 there), and a group does not, so that world would lose its row – the false one of "count(*) > 1" came out at 1/2 instead of 3/4 over two rows at one half. The block is copied once per truth instead, the comparison replaced by that truth and required by a HAVING, and the copies are united:

SELECT count(*) > 1 AS c FROM t --> SELECT true AS c FROM t HAVING count(*) > 1 UNION ALL SELECT false FROM t HAVING NOT (count(*) > 1)

with a third copy, NULL where the aggregate has no value, when it can have none. Each copy is a scalar aggregation whose HAVING is the provenance of its row, the empty world included.

Returns
The rewritten query, or NULL when no comparison of that shape is read as data here.

Definition at line 23093 of file provsql.c.

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

◆ rewrite_grouping_sets()

Query * rewrite_grouping_sets ( Query * q)
static

Rewrite a GROUP BY with GROUPING SETS, ROLLUP or CUBE into the UNION ALL of one GROUP BY per set.

In the rows of a set, the grouping expressions not in it are NULL, outside the aggregates, and GROUPING() is a constant; the empty set is an aggregation without GROUP BY (one row, even over no input row). Each GROUP BY is then rewritten as usual. The branches expose every entry (a set operation has no junk ones); an enclosing query keeps those of the statement, its DISTINCT, ORDER BY and LIMIT.

Definition at line 12094 of file provsql.c.

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

◆ rewrite_intersect()

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

Rewrite an INTERSECT into the deduplicated join of its sides.

A INTERSECT B, under set semantics, is SELECT DISTINCT a.* FROM A a, B b where every column of a matches that of b, two NULLs being equal: each row has the provenance (⊕ of the rows of A equal to it) ⊗ (⊕ of those of B). The provenance columns of the sides (a * over a tracked relation) are not compared; the target list keeps an entry for them, which the rewriting of the join then removes, so that what it reports removed is what the caller's target list has. ORDER BY and LIMIT move to the join. INTERSECT ALL is refused: it keeps min(m, n) copies of a row, without saying which, so no copy has a provenance of its own.

Definition at line 11863 of file provsql.c.

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

◆ rewrite_join_agg_token()

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

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

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

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

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

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

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

Definition at line 22063 of file provsql.c.

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

◆ rewrite_nested_antijoin()

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

Read a nested antijoin as the antijoin of the query's own rows against the projection of its bad pairs (see the block comment above).

Returns
Whether q was rewritten. Every shape this does not cover is declined silently, and the usual sublink handling then reports it.

Definition at line 17868 of file provsql.c.

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

◆ rewrite_non_all_into_external_group_by()

Query * rewrite_non_all_into_external_group_by ( Query * q)
static

Wrap a non-ALL set operation in an outer GROUP BY query.

UNION / EXCEPT (without ALL) would deduplicate tuples before ProvSQL can attach provenance tokens. To avoid this, the set operation is converted to UNION ALL / EXCEPT ALL and a new outer query is built that groups the results by all non-provenance columns, collecting tokens into an array for the provenance_plus evaluation.

After this rewrite the recursive call to process_query handles the now-ALL inner set operation normally.

Parameters
qQuery whose setOperations is non-ALL (modified to ALL in place).
Returns
New outer query that wraps q as a subquery RTE.

Definition at line 12261 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_plain_from_walker()

bool rewrite_plain_from_walker ( Node * node,
void * cx )
static

Walker: replace each FROM item plain(v), v a value of the row type of a table, by a subquery reading that table as plain SQL.

SELECT * FROM plain(NULL::t) reads t without tracking it: the subquery has t's columns at the positions of its row type (a NULL for a dropped column, NULL::uuid for its provenance column, named plain_provsql and dropped from the output of a * as any provenance column), and is marked inert, so that the rewriting leaves it alone.

Definition at line 13342 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_predicate_sublinks()

bool rewrite_predicate_sublinks ( const constants_t * constants,
Query * q )
static

Rewrite top-level EXISTS / IN WHERE conjuncts (optionally negated) over tracked relations 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. A body may mix tracked and untracked relations (e.g. a station lookup joined into the subquery); JOIN-syntax bodies arrive already canonicalised to the comma-join form by normalize_inner_joins. Conjuncts whose subselect is not decorrelatable (untracked / uncorrelated / outer-joined) are left untouched, so they hit the usual unsupported-subquery error.

Definition at line 18099 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_probability_event_mutator()

Node * rewrite_probability_event_mutator ( Node * node,
void * data )
static

Mutator: lift the RV surface that can appear in the target list.

Two rewrites, applied wherever they occur in the walked expression:

  • an RV-typed searched CASE with an RV-comparison guard becomes a rv_case(...) call (a gate_case);
  • a probability(<predicate>) Boolean-overload call whose argument carries a probabilistic comparison becomes probability_evaluate over the argument's event token. A purely-deterministic Boolean argument is left in place – the SQL body returns its 0/1 probability, keeping probability total over Booleans.

Recurses the whole (target-list) expression so both are rewritten wherever they appear (e.g. inside expected(CASE ... END)).

Definition at line 7886 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_probability_events()

void rewrite_probability_events ( const constants_t * constants,
Query * q )
static

Lift RV-comparison events in q's target list into their tokens.

Two related rewrites over the SELECT list (only), run early in process_query next to rewrite_cond_predicates:

  • probability(<predicate>) / probability_evaluate(<predicate>) Boolean overloads whose argument is a probabilistic event become probability_evaluate over the event token;
  • a projected RV comparison ("SELECT x > y") surfaces its gate_cmp uuid instead of raising in the runtime placeholder. WHERE / HAVING quals are deliberately untouched – those filter positions are handled by migrate_probabilistic_quals. A set-returning RV consumer over a CASE in the FROM list ("support(CASE ...)") is out of scope: materialise the CASE in a subquery / CTE first, then apply the consumer to the resulting random_variable column. No-op on a schema predating the Boolean probability overloads.

Definition at line 8013 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_rank_over_aggregate()

Query * rewrite_rank_over_aggregate ( const constants_t * constants,
Query * q )
static

Rewrite the ranks of a window ordered by an aggregate result into subqueries counting the rows before each row.

rank() / dense_rank() / row_number() OVER (ORDER BY count(*)) reads a value that varies between worlds, so the rows before a row do too: the frame machinery, which reads the ordering values of the database as it is, cannot track it. Counting the rows before instead compares the two aggregate results per pair of rows, which the rewriting of a correlated aggregate subquery and the comparison of two aggregate results already track; the count is then an aggregate result itself.

Fires on a query whose FROM is the single relation the window ranks – a subquery with one row per group, as an aggregation gives – whose ordering key is one of its agg_token columns, and which has no aggregate of its own. Returns NULL, leaving q alone, otherwise.

Definition at line 27674 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_target_list_exists()

bool rewrite_target_list_exists ( const constants_t * constants,
Query * q )
static

Rewrite the EXISTS values of q's select list (tl_exists_mutator).

Only this level's own target list, and only where the level is one the decorrelation can serve: it groups the outer rows, so a level that already groups or aggregates of its own has no room for it.

Definition at line 19636 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_uncorrelated_antijoin()

bool rewrite_uncorrelated_antijoin ( const constants_t * constants,
Query * q )
static

Rewrite an uncorrelated WHERE predicate that is satisfied by the empty group – NOT EXISTS, or "(SELECT count(*) FROM Q) <op> const" with "0 <op> const" true (e.g.

"< k", "<= k", "= 0") – into the EXCEPT-ALL antijoin.

Such a predicate is "NOT P" for a P that is FALSE on the empty group (EXISTS, count(*) >= k…), so it is the m-semiring antijoin "R ⊗ (1 ⊖ ⟦P⟧)". We materialise ⟦P⟧ as the one-row HAVING-gated subquery D = "SELECT 1 FROM Q [WHERE w] HAVING count(*) <negated op> const" (count(*) always yields a row, so ⟦P⟧ is correctly captured even when the group is empty), then take the difference "R EXCEPT ALL π_R(R × D)" via oj_build_diff – ProvSQL's NOT-IN EXCEPT-ALL, giving each kept tuple "R(r) ⊖ (R(r) ⊗ ⟦P⟧) = R(r) ⊗ (1 ⊖ ⟦P⟧)", multiplicity preserved and correct in every semiring.

Runs before rewrite_predicate_sublinks / move_uncorrelated_where_predicates: those would instead push the raw predicate into a HAVING-gate, whose empty group is gate_zero – dropping exactly the world this predicate selects (a silent under-count: count(*)=0 → p=0, count(*)<2 → P(=1) not P(≤1)).

Definition at line 18880 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewrite_uncorrelated_membership()

bool rewrite_uncorrelated_membership ( const constants_t * constants,
Query * q )
static

Read every uncorrelated membership test of q as a join against the deduplicated body, where the block's own FROM holds something that is not a base relation.

Runs BEFORE the predicate-sublink lowering: that one turns "x IN (body)" into "(SELECT count(*) FROM body WHERE body.k = x) >= 1", which makes the body correlated and hands the result to a decorrelation that wants to group the block by base relations – and declines beside a subquery in the FROM. Taken as a join first, the condition never becomes a count at all.

Returns
Whether anything moved.

Definition at line 19293 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ row_without_provsql()

Node * row_without_provsql ( wholerow_ctx * ctx,
Var * v )
static

The row of the columns of v's relation or subquery other than provsql, as an anonymous record; NULL where the whole row is (the null-padded side of an outer join).

The columns of a subquery are those of its target list: the provenance column the rewriting will add to it is not among them.

Definition at line 26298 of file provsql.c.

Here is the caller graph for this function:

◆ rows_are_products_of_distinct_inputs()

bool rows_are_products_of_distinct_inputs ( const Query * q,
List ** relids )
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).

Whether every output row of q has a provenance that is a product of distinct input tokens.

True when nothing in q merges rows or subtracts them (no grouping, aggregation, DISTINCT, set operation, sublink, at any level) and no relation occurs twice: the token of a row is then the ⊗ of one token per relation, all different. Such a circuit is read-once, the independent probability method always applies to it, and the order keys and certificate of the inversion-free route, which comes after it in the default chain, would never be read. They cost a gate and a key per input per output row, so they are not built.

Parameters
qquery to inspect, before provenance discovery
relidsrelations met so far (in/out)

Definition at line 24171 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rowstar_mutator()

Node * rowstar_mutator ( Node * node,
void * cx )
static

Mutator: leave the provsql column that * expands to out of the anonymous rows ROW(t.

*), at any depth of the statement.

An anonymous record has positional field names (f1, f2...), so the other fields are unchanged; a row cast to the table's own type (ROW(t.*)::t) is typed and keeps every column.

Definition at line 30391 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rte_column_is_aggregate()

bool rte_column_is_aggregate ( const constants_t * constants,
RangeTblEntry * rte,
AttrNumber attno )
static

Whether column attno of the subquery rte is an aggregate result: its entry is an aggregate, or the agg_token it becomes once the subquery is rewritten.

Definition at line 27069 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_BoolExpr_to_provenance()

FuncExpr * rv_BoolExpr_to_provenance ( BoolExpr * be,
const constants_t * constants,
bool negated )
static

Convert a Boolean combination of RV comparisons into a provenance_times / provenance_plus expression.

Same De Morgan handling as having_BoolExpr_to_provenance: under negation, AND ↔ OR (which means PROVENANCE_TIMES ↔ PROVENANCE_PLUS). NOT flips negated and recurses.

Definition at line 6729 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_cmp_index()

int rv_cmp_index ( const constants_t * constants,
Oid funcoid )
static

Test whether funcoid is one of the random_variable_* comparison procedures, and if so return its ComparisonOperator index.

Parameters
constantsExtension OID cache.
funcoidProcedure OID to test (typically OpExpr->opfuncid).
Returns
Index in [0..6) on match, -1 otherwise. Match indices line up with ComparisonOperator (EQ=0, NE=1, LE=2, LT=3, GE=4, GT=5).

Definition at line 6606 of file provsql.c.

Here is the caller graph for this function:

◆ rv_cmp_walker()

bool rv_cmp_walker ( Node * node,
void * ctx )
static

The row token a displayed aggregate value is filtered by, or NULL when every row of q holds in the database as it is.

The displayed value of an aggregate is PostgreSQL's aggregate over the rows the rewritten query keeps. Some are kept only for their provenance, false in the actual data: the null-padded rows of a lowered outer join that do have a match, the groups a HAVING rejects, the rows beyond a rank-filtered LIMIT. When token_may_be_false says such rows can reach the aggregate, the value reads only the rows whose token holds (plain_truth), so that it is the value plain SQL computes on the same data. The comparisons on random variables among prov_atts have no value there and are left out.

Walker: does the expression call one of the random_variable comparison gate builders?

Definition at line 9927 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_Expr_to_provenance()

FuncExpr * rv_Expr_to_provenance ( Expr * expr,
const constants_t * constants,
bool negated )
static

Dispatch a WHERE sub-expression to the appropriate RV converter.

Entry point for the mutual recursion between rv_BoolExpr_to_provenance and rv_OpExpr_to_provenance_cmp.

Definition at line 6779 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rv_OpExpr_to_provenance_cmp()

FuncExpr * rv_OpExpr_to_provenance_cmp ( OpExpr * opExpr,
const constants_t * constants,
bool negated )
static

Convert a single RV-comparison OpExpr into a provenance_cmp() FuncExpr returning UUID.

If negated is true the operator OID is replaced by its negator (so NOT (a > b) becomes a ≤ b at the provenance level), exactly as having_OpExpr_to_provenance_cmp does.

Parameters
opExprThe comparison expression from the WHERE clause. Must satisfy rv_cmp_index(opExpr->opfuncid) ≥ 0; callers are responsible for the type check.
constantsExtension OID cache.
negatedWhether the expression appears under a NOT.

Definition at line 6676 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalar_agg_over_uncorrelated_sublinks()

Query * scalar_agg_over_uncorrelated_sublinks ( const constants_t * constants,
Query * q )
static

Move an aggregation without GROUP BY into a subquery, leaving out its uncorrelated scalar subqueries.

move_uncorrelated_sublinks_to_from joins such a subquery to the FROM, and refers to its value in the target list. In an aggregation without GROUP BY, that reference is to a column neither grouped nor aggregated, which reads nothing when the aggregation has no input row. SELECT count(*), (SELECT count(*) FROM t) FROM r is rewritten as SELECT a.count, (SELECT count(*) FROM t) FROM (SELECT count(*) FROM r) a, whose ORDER BY and LIMIT it takes; the subquery is then moved at that level, which has one row. Returns NULL, leaving q alone, when there is no such subquery, or when an entry reads provenance(), which the rows of the subquery would not give.

Definition at line 25754 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalar_distinct_as_cross_join()

void scalar_distinct_as_cross_join ( Query * q,
int base,
int n )
static

Turn the scalar query q rewritten by rewrite_agg_distinct into a cross join of one-row subqueries.

The n outer subqueries (range-table entries base + 1 to base + n) each compute one AGG(DISTINCT) as one row. The query itself, a scalar aggregation over its FROM and WHERE, also returns one row, but when its WHERE keeps none, a Var of that row on an outer subquery reads an empty row. The FROM, the WHERE and the aggregates without DISTINCT move to one more subquery, and the query is the cross join of these subqueries, without aggregation.

Definition at line 9434 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalar_distinct_mutator()

Node * scalar_distinct_mutator ( Node * node,
void * cx )
static

Mutator: renumber the Vars on the outer subqueries of rewrite_agg_distinct, and replace each remaining aggregate by a Var on the subquery computing it.

Definition at line 9399 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_ancestors()

Datum set_ancestors ( PG_FUNCTION_ARGS )
extern

Replace the ancestor half of a relation's row, keeping its kind / block_key.

Silently no-op when relid has no row 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 315 of file table_info.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_operation_as_query()

Query * set_operation_as_query ( SetOperationStmt * stmt,
List * old_rtable )
static

Turn the set-operation subtree stmt into a query of its own.

Builds what the parser produces for a parenthesised set operation used as a leaf: a Query whose range table holds the leaves of stmt, whose setOperations is stmt, and whose target list is made of Var nodes on the leftmost leaf, typed by the column descriptions of stmt and named after that leaf's columns.

Definition at line 11779 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_operation_has_except_all()

bool set_operation_has_except_all ( Node * node)
static

Whether a set-operation tree contains an EXCEPT ALL node.

Definition at line 29106 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_operation_leftmost_leaf()

Index set_operation_leftmost_leaf ( Node * node)
static

Range-table index of the leftmost leaf of a set-operation tree.

Definition at line 11744 of file provsql.c.

Here is the caller graph for this function:

◆ set_operation_move_leaves()

void set_operation_move_leaves ( Node * node,
List * old_rtable,
List ** rtable )
static

Move the leaves of node into rtable, renumbering them.

node is a set-operation tree over the range table old_rtable; its RangeTblRef leaves are rewritten in place to index rtable, to which the entries they named are appended in traversal order.

Definition at line 11757 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_table_info()

Datum set_table_info ( PG_FUNCTION_ARGS )
extern

Forward declaration of the C SQL entry points.

Forward declaration of the C SQL entry points.

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'. The relation's existing ancestors are preserved.

Definition at line 244 of file table_info.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_union_column_type()

void set_union_column_type ( Node * n,
int i,
Oid type )
static

Set the type of column i on every node of a set-operation tree.

Definition at line 20503 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setop_column_explodable()

bool setop_column_explodable ( const constants_t * constants,
Query * q,
Node * n,
AttrNumber attno )
static

Whether column attno of every arm of the set-operation tree n of q is an aggregate that can be exploded.

An arm that aggregates nothing there – a constant row, a column of a relation – is not explodable: its value would be deduplicated against values that are one per possible world.

Definition at line 22460 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setop_column_has_aggregate()

bool setop_column_has_aggregate ( const constants_t * constants,
Query * q,
Node * n,
AttrNumber attno )
static

Whether column attno of some arm of the set-operation tree n of q is an aggregate result.

Definition at line 22477 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sort_key_reads_agg_null_walker()

bool sort_key_reads_agg_null_walker ( Node * node,
void * cx )
static

Walker: does the expression hold an IS [NOT] NULL of an aggregate result?

Such a test in a sort key is read on the value the aggregate has in the database as it is, which orders the rows as plain SQL would – and says nothing, where sorting on the value itself says so. In the select list the same test is a truth per world and explodes (rewrite_explode_agg_cmp_truth); a sort key is no answer, so it is not exploded, which is exactly why the loss has to be reported instead.

Definition at line 26506 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sort_key_reads_agg_value()

bool sort_key_reads_agg_value ( const constants_t * constants,
Query * q )
static

Whether the LIMIT / OFFSET of q, a query over tracked relations, is rewritten into the filter of a rank (lower_limit_to_rank).

Whether a sort key of q reads the value of an aggregate.

That needs an ORDER BY on values that are the same in every world, no plain() marker, a query that keeps its input rows (no aggregation, grouping, DISTINCT, set operation or set-returning function), limits that are constants or parameters. OFFSET with WITH TIES is left out: the rows it skips are counted by position, among peers too.

An aggregation ordered by one of its aggregates (GROUP BY g ORDER BY count(*) DESC LIMIT k, the top-k of the groups) is lowered too: the rank of a group by an aggregate result is rewritten into the count of the groups before it (rewrite_rank_over_aggregate).

Definition at line 29261 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sort_on_plain_values()

void sort_on_plain_values ( const constants_t * constants,
Query * q,
bool top_level )
static

Sort an ORDER BY on an aggregate result on its value.

An agg_token has no ordering. Each sort key of q whose column is an agg_token (an aggregate of q, or a subquery's aggregate result) moves to a new junk column holding the value, read in the type the sort operator was chosen for: the value plain SQL computes on the same data. The column itself keeps its agg_token, and each row its provenance; the order is that of the database as it is, whatever the world. At the top level of the statement, a warning says so. A key also used for grouping or DISTINCT is left alone, refused elsewhere.

Definition at line 26572 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sortby_position()

int sortby_position ( Node * n)
static

The integer of a positional ORDER BY item, or 0.

Definition at line 30170 of file provsql.c.

Here is the caller graph for this function:

◆ sortgroupref_is_key()

bool sortgroupref_is_key ( Query * q,
Index ref )
static

Whether ref is a GROUP BY or DISTINCT key of q.

Definition at line 22405 of file provsql.c.

Here is the caller graph for this function:

◆ sortgroupref_is_sort_key()

bool sortgroupref_is_sort_key ( Query * q,
Index ref )
static

Whether ref is ordered by, or by a window of, q.

Definition at line 13769 of file provsql.c.

Here is the caller graph for this function:

◆ split_aggregation_into_subquery()

Query * split_aggregation_into_subquery ( Query * q)
static

Compute the aggregation of q in a subquery, q keeping what reads its results.

The aggregation – the FROM, the GROUP BY, the HAVING and the aggregates of the target list – moves to a subquery exposing its grouping columns and its aggregates, and q reads those columns. What it does with them is left to it: the windows of split_window_over_aggregates, the DISTINCT of split_distinct_over_aggregates.

Returns NULL, leaving q alone, when the aggregation has nothing to expose or a grouping expression is not one of its columns.

Definition at line 26926 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ split_aggregation_over_sublinks()

Query * split_aggregation_over_sublinks ( const constants_t * constants,
Query * q )
static

Move the join and the WHERE of an aggregation or a DISTINCT whose WHERE tests subqueries into a subquery of its own.

SELECT count(*) FROM r WHERE r.a IN (SELECT ...) is rewritten as SELECT count(*) FROM (SELECT r.a FROM r WHERE r.a IN (SELECT ...)) s: the subquery tests are then in a query that keeps its input rows, which their rewritings handle, and the grouping, aggregates, HAVING, DISTINCT, ORDER BY and LIMIT apply to its rows. The subquery exposes the columns the rest reads. Returns NULL, leaving q alone, unless the WHERE has a subquery over a tracked relation and neither the target list nor the HAVING has one.

Definition at line 25550 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ split_distinct_over_aggregates()

Query * split_distinct_over_aggregates ( const constants_t * constants,
Query * q )
static

Compute the aggregation of q in a subquery when a DISTINCT of its own deduplicates its results.

SELECT DISTINCT count(*) ... GROUP BY g deduplicates values that are one per possible world, which is no operation on the data as it is: the aggregation moves to a subquery and the DISTINCT stays above it, where the aggregate is exploded into one row per value it takes (rewrite_explode_agg_value) and the deduplication is over data.

Returns NULL, leaving q alone, when q has no DISTINCT over an aggregate of its own, or on a shape it does not split (a DISTINCT ON, a window, a set operation, a WITH, a LIMIT).

Definition at line 27031 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ split_predicate_sublinks()

Query * split_predicate_sublinks ( const constants_t * constants,
Query * q )
static

Test the subqueries of a WHERE one after the other: move all but the first into an enclosing query.

SELECT ... FROM r WHERE c AND EXISTS(A) AND EXISTS(B) becomes SELECT ... FROM (SELECT ... FROM r WHERE c AND EXISTS(A)) s WHERE EXISTS(B), the references to r, in B too, reading the columns s exposes. Each level then has a single subquery test, which its rewriting handles (the enclosing query is split again if more remain). Returns NULL, leaving q alone, unless two conjuncts at least test subqueries over tracked relations; not for a query with a WITH, whose references would have to follow.

Definition at line 25446 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ split_targetlist_sublinks()

Query * split_targetlist_sublinks ( const constants_t * constants,
Query * q )
static

Compute the subquery expressions of a target list in a subquery.

The rewriting of a scalar subquery handles one of them in a query that keeps its input rows. With several, or next to aggregates, a window or a DISTINCT, the join and the WHERE move into a subquery that computes them as columns (the first one only when the query keeps its rows; the enclosing query is then split again), and the rest reads those columns. In a grouped query, a subquery moves if the columns of the query it reads are grouping expressions: its value is the same for the rows of a group. Returns NULL, leaving q alone, when there is nothing to do; not for a query with a WITH, or with a subquery in its HAVING.

Definition at line 25330 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ split_window_over_aggregates()

Query * split_window_over_aggregates ( const constants_t * constants,
Query * q )
static

Definition at line 26899 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ statement_sort_items()

List * statement_sort_items ( Query * q,
const char * src )
static

The ORDER BY items of the statement q was analysed from, re-read from its text, or NIL.

Parse analysis resolves a position (ORDER BY 3) to a target entry and keeps no trace of it: the text is the only place left that says whether a key was a position. A CREATE VIEW is analysed with the location of the whole statement, hence the view's query; the query of a CREATE TABLE AS is within its statement.

Definition at line 30196 of file provsql.c.

Here is the caller graph for this function:

◆ strip_agg_cast()

Node * strip_agg_cast ( Node * n)
static

Strip one cast layer around an aggregate: a single-argument cast (the agg_token -> numeric cast the aggregate-lowering pass wraps, a cast the parser inserted), or the value of an aggregate read through its text (frozen_agg_value).

Definition at line 4956 of file provsql.c.

Here is the caller graph for this function:

◆ strip_given_markers()

List * strip_given_markers ( const constants_t * constants,
Query * q )
static

Strip given(evidence) whole-tuple conditioning markers from the visible projection, returning the captured evidence expressions.

Walks q's target list for visible (non-resjunk) entries whose expression is a provsql.given(uuid) FuncExpr – the consumed marker emitted by the prefix | operator / given() call. Each match is removed from the projection (its resno renumbered like remove_provenance_attributes_ select), and its single argument (the per-row evidence token) is collected into the returned list, in target-list order. The caller wraps the query's output provenance in cond(row_provenance, evidence) for each captured expression, so multiple markers accumulate as a conjunction of evidence (cond folds "(X|A)|B = X|(A∧B)").

Returns NIL when the query carries no marker (the common case, no cost beyond the walk). q's target list is modified in place.

Definition at line 3712 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ strip_provsql_equalities()

Node * strip_provsql_equalities ( const constants_t * constants,
Query * q,
Node * quals )
static

quals without the equalities between two provsql columns.

Definition at line 26142 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ strip_provsql_join_columns()

bool strip_provsql_join_columns ( Node * node,
void * cx )
static

Walker: a NATURAL join of two tracked relations, or a join USING their provsql column, does not join on it.

Both relations have a column provsql, which NATURAL makes a join column: the join would then require equal provenance tokens and keep no row. The column is the provenance of each side, not data; the equality is removed from the join condition, in this query and the queries nested in it. The merged column the join exposes is dropped from the output as any provsql column is.

Definition at line 26208 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ strip_provsql_join_quals()

void strip_provsql_join_quals ( const constants_t * constants,
Query * q,
Node * jt )
static

Remove the provsql columns from the join conditions of the NATURAL and USING joins of jt (see strip_provsql_join_columns).

Definition at line 26172 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_body_reads_provsql()

bool sublink_body_reads_provsql ( Node * node,
void * cx )
static

Walker: does a sublink of this level have a body that READS the provenance column?

The columns of an EXISTS body are not read at all, so the provsql that a "SELECT @c *" over a tracked relation expands to is no such read; for every other kind the body's columns are the value, so its whole tree counts. Does not descend into range-table subqueries: they are rewritten on their own.

Definition at line 28983 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_classify_walker()

bool sublink_classify_walker ( Node * node,
void * cx )
static

Walker classifying each tracked SubLink of a query as either a still-unsupported direct form or an arithmetic-nested one.

Stops descending at a tracked sublink (its subselect is Postgres' business once we decide to pass it through); keeps descending through untracked sublinks so a tracked one nested deeper is still found.

Definition at line 12956 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_is_inert()

bool sublink_is_inert ( SubLink * sl)
static

Does sl wrap a recorded inert provenance()-fetch subselect?

Such a SubLink is an untracked scalar value: the decorrelation / move-to-FROM passes must leave it alone (moving or aggregating it would couple its relation into the outer lineage and wrap the token in an aggregate gate).

Definition at line 12564 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_over_tracked_walker()

bool sublink_over_tracked_walker ( Node * node,
void * cx )
static

Walker: set found if a SubLink whose subselect (transitively) involves a provenance-tracked relation is reached.

Definition at line 12841 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sublink_reason_of()

sublink_reason sublink_reason_of ( const char * scope,
const char * tag,
const char * msg )
static

Build a sublink_reason.

Definition at line 12989 of file provsql.c.

Here is the caller graph for this function:

◆ sublink_unsupported_reason()

sublink_reason sublink_unsupported_reason ( const constants_t * constants,
Query * q,
SubLink * sl )
static

Definition at line 13043 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ subselect_is_pure_provenance_fetch()

bool subselect_is_pure_provenance_fetch ( const constants_t * constants,
Query * sub )
static

Whether sub's sole non-junk output is a bare provenance() call.

Checked before resolution (the target is still the raw provenance() FuncExpr). The supported shape is deliberately narrow – a plain scan projecting only provenance(): exactly one visible target entry, and it is provenance(), with no aggregation / grouping / HAVING / set-op / DISTINCT / window (those carry probabilistic-provenance semantics an inert, physically-evaluated fetch would not honour, so they stay on the ordinary path). A subselect bringing any other column likewise stays correlated.

Definition at line 12581 of file provsql.c.

Here is the caller graph for this function:

◆ takes_agg_token()

bool takes_agg_token ( Oid funcid,
int i,
const constants_t * constants )
static

Whether argument i of function funcid takes an agg_token as it is: a parameter of type agg_token, or a polymorphic one of a ProvSQL function (expected(cnt), sr_formula(cnt, ...)).

Definition at line 585 of file provsql.c.

Here is the caller graph for this function:

◆ targetlist_sublink_mutator()

Node * targetlist_sublink_mutator ( Node * node,
void * cx )
static

Mutator: the subquery expressions to compute in the subquery become references to its columns; the Vars of the query, in the target list and in the subqueries left, references to the columns exposing them.

Definition at line 25275 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ te_reads_agg_value()

bool te_reads_agg_value ( const constants_t * constants,
Query * q,
TargetEntry * te )
static

Whether the entry te of q reads the value of an aggregate.

Definition at line 29247 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tl_exists_mutator()

Node * tl_exists_mutator ( Node * node,
void * cx )
static

Rewrite an EXISTS of the select list into the count of its body.

EXISTS (Q) in the select list is a Boolean VALUE, not a condition: the semantics reads it as the count column of G_c(R,Q) under ">= 1", an aggregate expression whose value in a world is the Boolean SQL computes there (NOT EXISTS is "= 0"). Written as that comparison here, it takes the road the same test in WHERE takes: the aggregate-body arm of decorrelate_scalar_sublinks builds "R @c ⟕ @c Q" grouped by R and turns the body's count(*) into count(Q.key), and the comparison is then an ordinary one of an aggregate against a constant – which rewrite_explode_agg_cmp_truth explodes into the two rows the semantics asks for, annotated "α⊗δ(⊕β)" and "α⊗(𝟙⊖⊕β)", the semijoin's and the antijoin's.

A term over the value is rewritten in place, so "CASE @c WHEN @c EXISTS @c (Q) @c THEN @c ..." is covered as well. A body the decorrelation cannot take is left alone.

Definition at line 19599 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_numeric()

Node * to_numeric ( Node * n)
static

n as numeric, where it is not one already.

Definition at line 6008 of file provsql.c.

Here is the caller graph for this function:

◆ token_may_be_false()

bool token_may_be_false ( const constants_t * constants,
Query * q,
Node * e )
static

Whether a provenance expression of q may be false in the database as it is, every input tuple present.

A token built only by ⊗, ⊕, δ, projections and equalities over the tuples of TID / BID relations is true there; so is the provenance column of a subquery built that way. A monus (a lowered outer join, EXCEPT, NOT IN), a comparison (a HAVING, a WHERE on an uncertain value, a rank-filtered LIMIT), a relation of derived tokens, or anything not recognized may be false.

Definition at line 9844 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ top_limit_is_truncation()

bool top_limit_is_truncation ( const constants_t * constants,
Query * q )
static

Whether the ORDER BY ... LIMIT / OFFSET of q, the top level of a statement over tracked relations, stays a truncation of the actual result without being marked so.

An ORDER BY ... LIMIT is read in every possible world when limit_lowerable accepts it. Over an aggregation, a DISTINCT, a set operation, or sort keys whose values vary between worlds, it is not: the statement then shows the first rows of the actual result, which plain() says explicitly. A LIMIT with no ORDER BY at all is such a truncation too: SQL leaves which rows it keeps open, and the rows the actual data gives are not the rows another world would give – one of them absent, the result there holds a row this answer does not. It is reported, not read: under the rank semantics no row precedes another there, so every row would tie at rank 1 and WITH TIES would keep them all, but whoever writes LIMIT k asks for k rows and would not expect the whole relation back. Not reported on a schema without plain().

Definition at line 29172 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tracked_cte_of()

Query * tracked_cte_of ( const constants_t * constants,
List * ctes,
const RangeTblEntry * r )
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.

The query of a WITH entry r names in ctes, when that entry is tracked and yields exactly one row in every possible world.

A scalar aggregation (aggregates, no grouping, no set operation, no DISTINCT, no LIMIT) has one row whatever the data, so a body reading it is a one-row derived table as it stands: it needs neither the choose() of a value body nor the HAVING that gates the worlds with more than one row.

Definition at line 18500 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tracked_sublink_count_walker()

bool tracked_sublink_count_walker ( Node * node,
void * cx )
static

Walker: count the sublinks over a tracked relation, one by one (not one per clause), without descending into one that is already counted.

Definition at line 13006 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tracked_sublink_remains_walker()

bool tracked_sublink_remains_walker ( Node * node,
void * data )
static

Walker over a rewritten query: a sublink, at any level, whose body still reads a tracked relation for its data.

The rewriting replaces every subquery expression it supports; one left over (the argument of a set-returning function in the target list, ...) is evaluated by Postgres on the data as it is.

Definition at line 14026 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tracked_value_sublink_walker()

bool tracked_value_sublink_walker ( Node * node,
void * data )
static

Walker over the expressions of one query level: a sublink whose body reads a tracked relation for its data.

A body whose output columns are all provenance tokens ((SELECT provsql FROM t WHERE ...), provenance(), array_agg(provsql)), other than an EXISTS, fetches the tokens to work on them, not data: it is not counted. The body itself is another level, not walked here.

Definition at line 13862 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tracked_wholerow()

Var * tracked_wholerow ( wholerow_ctx * ctx,
Node * n )
static

The whole-row Var n of a provenance-tracked relation, or of a subquery the rewriting tracks (a view, a derived table), of the range table of the query of ctx, or NULL.

Definition at line 26255 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transform_distinct_into_group_by()

void transform_distinct_into_group_by ( Query * q)
static

Convert a SELECT DISTINCT into an equivalent GROUP BY.

ProvSQL cannot handle DISTINCT directly (it would collapse provenance tokens that should remain separate). This function moves every entry from q->distinctClause into q->groupClause (skipping any that are already there) and clears q->distinctClause.

Parameters
qQuery to modify in place.

Definition at line 11568 of file provsql.c.

Here is the caller graph for this function:

◆ transform_except_into_join()

bool transform_except_into_join ( const constants_t * constants,
Query * q )
static

Rewrite a difference node into a LEFT JOIN with monus provenance.

The node is the internal EXCEPT ALL of two leaves, the multiset difference of the algebra: the one left under the outer GROUP BY of a non-ALL EXCEPT, and the ones built by outer-join lowering and antijoins (an EXCEPT ALL written by the user over tracked relations is refused earlier by refuse_except_all). This function transforms:

SELECT … FROM A EXCEPT ALL SELECT … FROM B

into a LEFT JOIN of A and B on all non-provenance columns, compared with IS NOT DISTINCT FROM (two NULLs match, as in SQL's set operations), clears setOperations, and leaves the monus token combination to make_provenance_expression (which will see SR_MONUS). The right arm has been grouped on its columns beforehand by group_set_difference_right_arm, so that a left tuple meets one right row carrying the ⊕ of its equal right tuples.

A set operation as an operand raises an error; nest_set_operations has turned such operands into leaves before this point.

Parameters
constantsExtension OID cache.
qQuery to rewrite in place.
Returns
Always true (errors out on unsupported cases).

Definition at line 14357 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_lower_agg_case()

Node * try_lower_agg_case ( Node * node,
const constants_t * constants )
static

A CASE over aggregates, or what becomes one (GREATEST / LEAST, COALESCE, NULLIF), lowered to its agg_case gate.

The target list is lowered by rewrite_agg_case_mutator as a whole; a HAVING clause is read expression by expression instead, so this lowers the one expression the reader has in hand. Returns NULL where the shape declines to lower, and the caller then reads the value as a plain one.

Definition at line 7777 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_push_into_aggref()

Node * try_push_into_aggref ( OpExpr * op,
const constants_t * constants )
static

Push distributive constant arithmetic into an aggregate's argument.

Rewrites f(x) <op> c to f(x <op'> c) when f distributes over the arithmetic, so the result is a clean aggregate over transformed per-row values rather than a gate_arith wrapping the aggregate. Run before the aggregate is lowered, so the provenance machinery then builds an ordinary gate_agg. Only the cases that distribute without flipping the aggregate and without integer-division rounding are handled (the rest fall through to the gate_arith path):

  • sum, avg: *c (either side), unary -; avg also +c / -c.
  • min, max: +c (either side), -c (aggregate on the left). The transformed argument must keep the original argument's type (so the aggregate's function/type stay valid); otherwise no push happens. Returns the rewritten Aggref, or NULL when op is not such a case.

Definition at line 10795 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_swap_agg_arith()

Node * try_swap_agg_arith ( OpExpr * op,
const constants_t * constants )
static

Definition at line 10265 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_swap_agg_func()

Node * try_swap_agg_func ( FuncExpr * f,
const constants_t * constants )
static

The agg_token counterpart of a function over an aggregate result, or NULL where there is none.

ln(sum(x)) reads, as the query writes it, the value the sum takes in the database as it is: the function is applied to a number, and what it gives is not tracked. ProvSQL defines the same functions over agg_token, whose gate carries the operation (gate_arith) and computes it in every world, so the call is re-resolved onto them – the swap try_swap_agg_arith does for the arithmetic operators.

Only a function of pg_catalog whose counterpart exists is swapped; one of anything else, or over a value that is no aggregate result, is left to read the value.

Definition at line 10451 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ type_has_equality()

bool type_has_equality ( Oid type)
static

Does type have a default equality operator?

Definition at line 17242 of file provsql.c.

Here is the caller graph for this function:

◆ unc_from_has_non_relation()

bool unc_from_has_non_relation ( Query * q)
static

Does q read something in its FROM that is not a base relation?

The decorrelation of a subquery condition groups the rows of the block by the relations of its FROM, which it wants to be base ones; a subquery there – an aggregate read as a value, a derived table – is not one, and the lowering declines. An UNCORRELATED membership test needs no grouping at all, so it can be read as a join instead, and this says when that is worth doing: only where the ordinary route would have declined, so the shapes it already handles keep the circuit they have.

Definition at line 19121 of file provsql.c.

Here is the caller graph for this function:

◆ unc_membership_lhs()

Node * unc_membership_lhs ( Node * node,
SubLink ** sl_out )
static

The left side of a top-level membership test "lhs IN (body)" whose body reads nothing outside it, or NULL.

PostgreSQL gives IN an ANY_SUBLINK whose testexpr compares the left side with a Param standing for the body's column. Only equality is a membership test; an op ANY with another operator is a different condition and is left alone.

Definition at line 19070 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unc_membership_to_join()

Node * unc_membership_to_join ( const constants_t * constants,
Query * q,
Node * conj )
static

Read an uncorrelated membership test as a join against the values of its body, deduplicated: "x IN (SELECT k FROM B WHERE p)" becomes "…, (SELECT DISTINCT k FROM B WHERE p) v WHERE x = v.k".

A semijoin against a set, which is what the condition says, and the ⊕ over the body's rows that share a value is the DISTINCT's own – tracked as any deduplication is. No grouping of the block is involved, so nothing here cares what else its FROM reads, which is the whole point: the count-predicate route wants base relations there and declines beside an aggregate read as a value.

Returns
The replacement qual, or NULL where the shape is not this one.

Definition at line 19151 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uncertain_value_walker()

bool uncertain_value_walker ( Node * node,
void * cx )
static

Walker: whether an expression of ctx->q may have different values in different possible worlds – an aggregate, a window function, a provenance, a random variable, or a subquery column computed so.

Definition at line 25016 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uncorr_qual_sublink_mutator()

Node * uncorr_qual_sublink_mutator ( Node * node,
void * cx )
static

Replace an uncorrelated scalar subquery of a qual by a column of the one-row derived table it becomes.

"WHERE @c v @c < @c (SELECT @c n @c FROM @c param)" reads one value of a tracked relation, the same in every row: such a subquery is the case of the translation without a correlation, a cross product with the one-row aggregation over its body (oj_build_uncorrelated_from_subquery, which picks the value with choose and keeps the at-most-one-row rule of a scalar subquery in a HAVING count(*) <= 1). The comparison then reads that column, an aggregate of the derived table, and is lowered like any comparison against an aggregate value.

Bodies that are correlated, or not a clean SELECT over tracked relations, are left where they are for the decorrelation to take.

Definition at line 19021 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_all_of_arms()

Query * union_all_of_arms ( Query * q,
List * arms )
static

The UNION ALL of arms, each a variant of q exposing every entry of its target list, under an outer query that keeps the entries of q, its DISTINCT, ORDER BY and LIMIT.

The arms are copies of q with the same target list, resno for resno, and no ordering or truncation of their own; a single arm is used as it is.

Definition at line 11962 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ union_leaves()

void union_leaves ( Node * n,
List ** leaves )
static

The range-table indexes of the leaves of a set-operation tree.

Definition at line 20493 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unmarked_window_walker()

bool unmarked_window_walker ( Node * node,
void * cx )
static

Definition at line 13637 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unplain_agg_walker()

bool unplain_agg_walker ( Node * n,
const constants_t * constants )
static

Find the first comparison of an aggregate against a constant.

Descends into a CASE only when the agg_case lowering would not take it: that one keeps a single row, carrying the branch values themselves, and is the better reading where it applies (a numeric CASE with an aggregate in a branch).

Walker: an aggregate of this level that no plain() wraps.

Definition at line 22840 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ untracked_level_with_tracked_sublink_walker()

bool untracked_level_with_tracked_sublink_walker ( Node * node,
void * data )
static

Walker: a query level the rewriting does not engage on (has_provenance) that has a subquery expression reading tracked data.

Such a level (a FROM-less query, a LATERAL body computing ARRAY(SELECT ... FROM t)) is left to Postgres, which evaluates its subqueries on the data as it is, so their data is treated as certain.

Definition at line 13898 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uuid_complement()

FuncExpr * uuid_complement ( Node * gate,
const constants_t * constants )
static

"𝟙 ⊖ gate", the complement of a Boolean gate.

Definition at line 5179 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uuid_const_gate()

FuncExpr * uuid_const_gate ( Oid funcid,
const constants_t * constants )
static

A no-argument gate constructor – gate_one(), gate_zero().

Definition at line 5150 of file provsql.c.

Here is the caller graph for this function:

◆ uuid_nary_gate()

FuncExpr * uuid_nary_gate ( Oid funcid,
List * elements,
const constants_t * constants )
static

provenance_plus / provenance_times over elements, each a UUID-valued gate expression, as the variadic call over an array the SQL functions take.

Definition at line 5158 of file provsql.c.

Here is the caller graph for this function:

◆ var_of_relation()

bool var_of_relation ( Query * q,
Var * v )
static

Whether v is a column of a table or view of q, directly or through joins (before PostgreSQL 13, * over a join expands to Vars of the join RTE).

Definition at line 30288 of file provsql.c.

Here is the caller graph for this function:

◆ warn_nested_limit()

void warn_nested_limit ( const constants_t * constants)
static

Report the freezing nested_limit_on_provenance calls for.

Definition at line 29304 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ warn_top_limit()

void warn_top_limit ( const constants_t * constants,
Query * q )
static

Report the freezing top_limit_is_truncation calls for.

Definition at line 29274 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wholerow_mutator()

Node * wholerow_mutator ( Node * node,
void * cx )
static

Mutator: replace the whole-row values of tracked relations read as any row (see hide_provsql_in_wholerows).

Definition at line 26402 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_aggregation_mutator()

Node * window_aggregation_mutator ( Node * node,
void * ctx )
static

Definition at line 11279 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_clause_of()

WindowClause * window_clause_of ( Query * q,
Index winref )
static

The WindowClause of q with reference winref.

Definition at line 11017 of file provsql.c.

Here is the caller graph for this function:

◆ window_count_star()

WindowFunc * window_count_star ( Index winref)
static

count(*) over the window winref.

Definition at line 26811 of file provsql.c.

Here is the caller graph for this function:

◆ window_frame_by_values()

bool window_frame_by_values ( const WindowClause * wc)
static

Whether the frame of a window is determined by the values of the rows, not by their positions.

The rows a frame holds are known in each possible world only if they do not depend on which of the other rows are present: "the rows whose ordering value is at most the current one's" is such a frame, "the previous row" is not, since it is the previous row that is present. Without ORDER BY, all rows are peers. RANGE frames are determined by values; GROUPS frames are when their bounds are unbounded or the current row (an offset counts peer groups, and which groups are present varies); ROWS frames only when they span the whole partition.

Definition at line 10974 of file provsql.c.

Here is the caller graph for this function:

◆ window_frame_has_current_row()

bool window_frame_has_current_row ( const WindowClause * wc)
static

Whether every frame of a window contains its current row.

The value of such a frame is only read in worlds where the frame has a row, as for a group of GROUP BY; otherwise the frame may be empty while the row exists, and the value is that of an aggregation over no row, as for a scalar aggregation.

Definition at line 10998 of file provsql.c.

Here is the caller graph for this function:

◆ window_kinds_walker()

bool window_kinds_walker ( Node * node,
void * cx )
static

Walker: which kinds of untracked window function q holds.

Definition at line 13618 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_outside_fragment()

bool window_outside_fragment ( Query * q,
WindowFunc * wf )
static

Walker: a window function outside any plain() call.

Whether a window function is one the fragment leaves out: its value is an offset into the partition or a rank ratio, or its frame is a positional one.

lag and its kind read the row a given number of rows away, and cume_dist and percent_rank a ratio of counts: which row that is, and what the counts are, depends on which rows are there, so there is no value to carry rather than one not carried yet. A frame counted in ROWS or in GROUPS says the same of an ordinary aggregate: sum(x) OVER (ORDER BY c ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) sums a set of rows that another world moves. A frame that spans the whole partition does not.

Definition at line 13584 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ window_reads_aggregate()

bool window_reads_aggregate ( Query * q)
static

Whether a window of q reads an aggregate of q itself.

Definition at line 26734 of file provsql.c.

Here is the caller graph for this function:

◆ windowfunc_outside_plain_walker()

bool windowfunc_outside_plain_walker ( Node * node,
void * cx )
static

Replace the window functions of q's target list by their provenance expressions, where they have one.

A window function leaves the rows of its input as they are, with their tokens; it is its value that depends on which rows are present, and that value becomes an agg_token. An ORDER BY on such a value sorts on what is displayed, which is presentation, as ORDER BY is: the sort key is moved to a junk copy of the original window call.

Returns
false if some window function was left untracked, its value an opaque scalar.

Walker: a window function that no plain() marker covers.

plain(f(x) OVER w) says the window value is meant as plain SQL, so the entry holding it is not one for the window rewriting to track: tracking it would make an agg_token the marker then has to read back, once per row, through the cast that warns that provenance is lost.

Definition at line 11335 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_agg_token_with_cast()

Node * wrap_agg_token_with_cast ( FuncExpr * prov_agg,
const constants_t * constants )
static

Wrap a provenance_aggregate FuncExpr with a cast to the original aggregate return type.

Parameters
prov_aggThe provenance_aggregate FuncExpr to wrap.
constantsExtension OID cache.
Returns
Cast FuncExpr wrapping prov_agg.

Definition at line 10013 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_body_grouping()

bool wrap_body_grouping ( const constants_t * constants,
Query * sub )
static

Move a sublink body that groups rows of its own into a derived table, so that what is left outside is the existence test the decorrelation already lowers.

"x @c IN @c (SELECT @c max(v) @c FROM @c u @c GROUP @c BY @c g)" becomes "x @c IN @c (SELECT @c m @c FROM @c (SELECT @c max(v) @c AS @c m @c FROM @c u @c GROUP @c BY @c g) @c d)": the grouping stays inside the derived table, which is tracked as any subquery of a FROM clause is – one row per group, annotated by the group – and the predicate over it is the semijoin R ⊗ ⊕D that build_count_predicate builds.

Only an uncorrelated body. A correlated one would have its rows grouped before the correlation is applied, which is a different query – unless the correlated column is a grouping key, where the groups are the same either way; that case is not lifted here.

And only a body whose columns are grouping keys, never an aggregate result: the value an aggregate takes is one per possible world, so "x @c IN @c (SELECT @c max(v) @c ... @c GROUP @c BY @c g)" is a comparison against a per-world value, which the semijoin's own correlation does not read (it answered every row of the outer relation, where SQL answers one). That shape stays refused, and the message keeps naming the body's grouping.

Returns
True when the body was wrapped (it now groups nothing of its own).

Definition at line 16711 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_body_setop()

bool wrap_body_setop ( const constants_t * constants,
Query * sub )
static

A sublink body that is a set operation becomes a derived table the semijoin reads.

"x IN (A INTERSECT B)" is "x IN (SELECT d.c FROM (A INTERSECT B) d)": the set operation is a query ProvSQL rewrites like any other – the provenance of an intersection, a union, a difference – and what is left at the sublink's own level is a plain SELECT over one derived table, which the decorrelation lowers as it lowers any other body. Relational algebra inside a semijoin, which is why it belongs at the bottom of the fragment chain rather than at its edge.

Only an UNCORRELATED body: an arm that reads the block above would have to carry that correlation into the derived table, which takes a LATERAL and a rule for distributing the correlation over the arms – the two ends are different rules and this is the first of them.

Definition at line 16846 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_body_sublinks()

bool wrap_body_sublinks ( Query * sub)
static

Move the subquery tests of the WHERE of a subquery body sub into a derived table of it.

x IN (SELECT a FROM Q WHERE t IN (SELECT ...)) has a body with a subquery test of its own, which the decorrelation of the outer test does not take; with it moved, x IN (SELECT d.a FROM (SELECT a FROM Q WHERE t IN (SELECT ...)) d), the body reads a derived table, whose own test its rewriting then handles. Only the conjuncts that read nothing outside the body move (the correlation stays where the decorrelation looks for it). Returns whether anything moved.

Definition at line 16600 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_in_annotate()

Expr * wrap_in_annotate ( const constants_t * constants,
Expr * expr,
const char * cert )
static

Wrap expr in a provsql.annotate(uuid, text) FuncExpr carrying cert.

Used by make_provenance_expression to attach the inversion-free tractability certificate to the per-row provenance root: the resulting annotation gate is transparent for every evaluator and carries cert in its extra (and folded into its UUID). cert is copied into a text Const.

Definition at line 23670 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_in_assume_boolean()

Expr * wrap_in_assume_boolean ( const constants_t * constants,
Expr * expr )
static

Wrap expr in a provsql.assume_boolean FuncExpr.

Used by make_provenance_expression when its caller (the safe-query rewrite path in process_query) flagged the result as needing the gate_assumed structural marker. Wrapping at expression-build time rather than at splice time means add_to_select and replace_provenance_function_by_expression both consume the already-wrapped expression, so every per-row root occurrence in the final target list – the auto-added provsql column and every substituted user-side provenance() call – carries the wrapper uniformly.

Parameters
constantsExtension OID cache.
exprProvenance expression to wrap.
Returns
A FuncExpr applying provsql.assume_boolean to expr.

Definition at line 23645 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_in_cond()

Expr * wrap_in_cond ( const constants_t * constants,
Expr * target,
Expr * evidence )
static

Wrap target in a provsql.cond(uuid, uuid) FuncExpr conditioning it on evidence.

Used by process_query when the query carries a given(...) marker: the per-row output provenance target is conditioned on the marker's evidence expression, so each output row's provenance becomes "cond(row_provenance, evidence)". evidence is the (per-row, possibly correlated) argument captured from the stripped given() term.

Definition at line 23697 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_inversion_free_markers()

void wrap_inversion_free_markers ( const constants_t * constants,
Query * q,
List * prov_atts,
const InvFreeMarker * markers,
int natoms )
static

Replace each certified atom's provenance Var in prov_atts with its per-input-marker-wrapped form (in place).

Definition at line 23808 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_join_tree()

void wrap_join_tree ( Query * q,
Node ** slot )
static

Move the join tree *slot of q into a subquery, which takes its place.

The subquery reads a copy of the range table, the entries not in the tree made placeholders (the indexes of the tree, in its conditions, stay valid); in q, the entries of the tree are placeholders, the tree's own join slot (or its relation's) holds the subquery, and the references to its relations read the columns the subquery exposes.

Definition at line 15472 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_mobius_or_null()

Expr * wrap_mobius_or_null ( const constants_t * constants,
Expr * mobius_call )
static

Wrap a Möbius call in mobius_or_null(...): the token if it roots a gate_mobius (a Möbius success), else NULL (a Möbius decline returns the lineage, never a gate_mobius).

Returns mobius_call unwrapped if the helper cannot be resolved (older schema).

Definition at line 8307 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wrap_random_variable_uuid()

Expr * wrap_random_variable_uuid ( Node * operand,
const constants_t * constants )
static

Wrap an expression returning random_variable in a binary-coercible cast to uuid.

Operand of the comparison may be a Var, a constant lifted by an implicit cast, or another OpExpr (e.g. a + b). random_variable and uuid share the same byte layout, so we emit a RelabelType node – the planner sees a zero-cost type relabel, the executor never dispatches through a runtime conversion function.

Definition at line 6627 of file provsql.c.

Here is the caller graph for this function:

◆ wrap_untracked_from_for_sublink()

bool wrap_untracked_from_for_sublink ( const constants_t * constants,
Query * q )
static

Give a block whose FROM reads no tracked relation a carrier for the provenance its condition has: a certain provenance column on the untracked source.

"SELECT … FROM (VALUES (4),(5),(6)) v WHERE NOT EXISTS (SELECT … FROM T WHERE T.k = v.id)" has a provenance -- "1 ⊖ ⊕" of the matching rows of T – and the only thing missing is an entry to carry it: the decorrelation reads the provenance of the block's own rows, and a VALUES list has none. Every row of one is there in every world, so a gate_one() column says exactly the truth and "1 ⊗ (what the subquery contributes)" is the answer. Without it the condition was frozen and read as plain SQL: the right rows, no provenance.

A VALUES in a FROM is a subquery entry over a VALUES one, so the column goes on that subquery's own target list – no new entry, and what the block already reads keeps its attribute number.

Returns
Whether q gained one.

Definition at line 19228 of file provsql.c.

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ agg_over_agg_frozen

bool agg_over_agg_frozen = false
static

An aggregate of the statement being planned reads the value of another as a plain value, the pair not being one the reaggregation carries (an avg of a count, a max of a sum).

Reported once, with the other freezings, rather than refusing the statement for that one pair.

Definition at line 235 of file provsql.c.

◆ freeze_statement

Query* freeze_statement = NULL
static

The statement being rewritten, whose relations a frozen part is compared with (report_freeze).

Definition at line 13510 of file provsql.c.

◆ last_tracked_sublink

SubLink* last_tracked_sublink = NULL
static

The last subquery expression tracked_value_sublink_walker found reading tracked data.

Definition at line 13305 of file provsql.c.

◆ nested_sublink_warned

bool nested_sublink_warned = false
static

Set when process_query warns of a nested scalar subquery, so that provsql_planner does not warn of it again.

Definition at line 14016 of file provsql.c.

◆ null_iff_no_value

const char* const null_iff_no_value[]
static
Initial value:
= {
"sum", "avg", "min", "max", "choose", "bool_and", "bool_or", "every",
"string_agg", "xmlagg", "stddev_pop", "var_pop", "bit_and", "bit_or",
"bit_xor", "range_agg", "range_intersect_agg", NULL}

The aggregates that are NULL exactly when they read no value: their NULL-ness is the presence of a value row.

count is never NULL and is read apart; a NULL-keeping aggregate (array_agg) is NULL exactly when it reads no row at all, which aggregate_keeps_nulls tells.

Definition at line 5195 of file provsql.c.

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Required PostgreSQL extension magic block.

Definition at line 103 of file provsql.c.

◆ prev_ExecutorEnd

ExecutorEnd_hook_type prev_ExecutorEnd = NULL
static

Definition at line 29640 of file provsql.c.

◆ prev_ExecutorStart

ExecutorStart_hook_type prev_ExecutorStart = NULL
static

Definition at line 29639 of file provsql.c.

◆ prev_planner

planner_hook_type prev_planner = NULL
static

Previous planner hook (chained).

Definition at line 206 of file provsql.c.

◆ prev_post_parse_analyze

post_parse_analyze_hook_type prev_post_parse_analyze = NULL
static

Previous post-parse-analysis hook (chained).

Definition at line 266 of file provsql.c.

◆ prev_ProcessUtility

ProcessUtility_hook_type prev_ProcessUtility = NULL
static

Definition at line 29723 of file provsql.c.

◆ provsql_absorptive_provenance

bool provsql_absorptive_provenance = false

Derived flag: the session's provenance class is 'absorptive' or 'boolean' – licenses constructions sound for absorptive semirings only (cyclic recursive queries stopped at the absorptive value fixpoint, the bounded-treewidth reachability route's certified circuits, absorptive circuit simplifications; tokens tagged accordingly). Set from the provsql.provenance GUC.

Derived flag of the provsql.provenance GUC: the session's provenance class is 'absorptive' or 'boolean', licensing constructions sound for absorptive semirings only (cyclic recursion stopped at the absorptive value fixpoint, tagged tokens).

Definition at line 139 of file provsql.c.

◆ provsql_active

bool provsql_active = true
static

true while ProvSQL query rewriting is enabled

Definition at line 110 of file provsql.c.

◆ provsql_aggtoken_text_as_uuid

bool provsql_aggtoken_text_as_uuid = false

When true, agg_token::text emits the underlying provenance UUID instead of "value (*)".

Global flag controlling agg_token text output: when true, agg_token_out emits the underlying provenance UUID instead of the default "value (*)" display string.

Definition at line 119 of file provsql.c.

◆ provsql_boolean_provenance

bool provsql_boolean_provenance = false

Derived flag: the session's provenance class is 'boolean' – enables the Boolean-only machinery (safe-query read-once rewrite, Boolean circuit simplifications), whose outputs are tagged so that semiring evaluations admitting no homomorphism from Boolean functions refuse to run on them. Set from the provsql.provenance GUC.

GUC: opt-in safe-query optimisation, declared in provsql.c.

Opt-in safe-query optimisation for hierarchical conjunctive queries; see the provsql.boolean_provenance GUC.

Definition at line 138 of file provsql.c.

◆ provsql_cmp_probability_evaluation

bool provsql_cmp_probability_evaluation = true

Run closed-form / analytic probability evaluators for gate_cmps inside probability_evaluate (currently the Poisson-binomial pre-pass for HAVING-COUNT; future MIN / MAX / SUM evaluators will gate on the same GUC); controlled by the provsql.cmp_probability_evaluation GUC.

Hidden diagnostic flag for the family of closed-form / analytic probability evaluators that resolve gate_cmps inside probability_evaluate ; see the provsql.cmp_probability_evaluation GUC.

Definition at line 136 of file provsql.c.

◆ provsql_dtree_max_subproblems

int provsql_dtree_max_subproblems = 0

Debug/safety hard cap on d-tree subproblems before it bails (0 = off; the chooser auto-budgets at the next-best method's cost regardless); provsql.dtree_max_subproblems GUC.

Definition at line 126 of file provsql.c.

◆ provsql_ess_warn_fraction

double provsql_ess_warn_fraction = 0.1

Effective-sample-size warning threshold for likelihood weighting: warn when the posterior ESS falls below this fraction of the accepted draws; controlled by the provsql.ess_warn_fraction GUC.

Definition at line 125 of file provsql.c.

◆ provsql_executor_depth

int provsql_executor_depth = 0
static

Executor nesting depth.

Tracks how deep we are inside Executor invocations. Incremented in provsql_executor_start, decremented in provsql_executor_end. The classifier NOTICE only fires when this is zero, which corresponds to the user's outermost statement being planned (before any executor entry). Plans built for PL/pgSQL function bodies that the rewriter inserts – provenance_times, provenance_plus, provenance_aggregate, ... – happen during execution of the user's plan, so they see depth >= 1 and skip the NOTICE.

Definition at line 220 of file provsql.c.

◆ provsql_fallback_compiler

char* provsql_fallback_compiler = NULL

Compiler used by BooleanCircuit::makeDD as the final fallback after interpretAsDD and tree-decomposition both fail; controlled by the provsql.fallback_compiler GUC (default "d4").

Compiler invoked as the final fallback in BooleanCircuit::makeDD when both interpretAsDD() and the in-process tree-decomposition path fail (the latter typically on treewidth blow-up).

Definition at line 121 of file provsql.c.

◆ provsql_gate_cache_size

int provsql_gate_cache_size = 65536

Byte budget, in kB, of the per-backend gate cache; provsql.gate_cache_size GUC.

Definition at line 128 of file provsql.c.

◆ provsql_hybrid_evaluation

bool provsql_hybrid_evaluation = true

Run the hybrid-evaluator simplifier inside probability_evaluate; controlled by the provsql.hybrid_evaluation GUC.

Run the hybrid evaluator (simplifier + per-cmp island decomposer) before dispatching a probability_evaluate query.

Definition at line 135 of file provsql.c.

◆ provsql_implicit_freeze

int provsql_implicit_freeze = PROVSQL_FREEZE_WARN

What an implicit freezing does: warn, or error; provsql.implicit_freeze GUC.

Definition at line 116 of file provsql.c.

◆ provsql_in_ctas

int provsql_in_ctas = 0
static

Depth of CREATE TABLE AS / SELECT INTO / CREATE MATERIALIZED VIEW being executed: their query's output is stored, not shown.

Definition at line 209 of file provsql.c.

◆ provsql_inert_subselects

List* provsql_inert_subselects = NIL
static

Walker (this query level only): true if an EXPR_SUBLINK whose body is a decorrelatable value subquery over a provenance-tracked base relation appears in an expression.

Lets the planner gate engage for a scalar subquery over a tracked relation even when the OUTER query has no tracked relation – decorrelate_scalar_ sublinks then handles it (wrapping the untracked outer with a certain gate_one() provenance and warning that its tuple provenance is lost). The shape conditions mirror decorrelate's subselect validation, so engagement implies the decorrelation succeeds (no engage-then-error regression); a non-decorrelatable scalar subquery still leaves the gate untouched and runs as plain SQL. Does not descend into nested Query / SubLink subselects.

Definition at line 12546 of file provsql.c.

◆ provsql_interrupted

bool provsql_interrupted = false

Global variable that becomes true if this particular backend received an interrupt signal.

Definition at line 109 of file provsql.c.

◆ provsql_inversion_free

bool provsql_inversion_free = true

Insert the inversion-free structured-d-DNNF path into the default probability chain (after independent, when a certificate is present); controlled by the provsql.inversion_free GUC.

Kill-switch for the inversion-free structured-d-DNNF probability path; see the provsql.inversion_free GUC.

Definition at line 137 of file provsql.c.

◆ provsql_joint_max_states

int provsql_joint_max_states = 65536

Per-bag DP state-count cap of the joint-width UCQ compiler (the true safety net); provsql.joint_max_states GUC.

Definition at line 129 of file provsql.c.

◆ provsql_joint_max_treewidth

int provsql_joint_max_treewidth = 10

Maximum joint treewidth the joint-width UCQ compiler attempts before declining (caller falls back to the ladder); provsql.joint_max_treewidth GUC.

Definition at line 127 of file provsql.c.

◆ provsql_joint_width

bool provsql_joint_width = true

Recognise unsafe UCQs at planner time and route their existence provenance through the joint-width compiler (on by default); the provsql.joint_width GUC is a debug-only switch to disable it.

Definition at line 130 of file provsql.c.

◆ provsql_kcmcp_server

char* provsql_kcmcp_server = NULL

Launch command for the managed KCMCP server (with a {endpoint} placeholder); controlled by the provsql.kcmcp_server GUC. Empty means no managed server is launched.

Launch command for the managed KCMCP knowledge-compiler server, set by the provsql.kcmcp_server run-time configuration parameter (PGC_SIGHUP).

Definition at line 122 of file provsql.c.

◆ provsql_last_eval_method

char* provsql_last_eval_method = NULL

Last probability evaluation method(s) used; exposed via provsql.last_eval_method.

Global variable holding the probability evaluation method(s) used by the most recent probability_evaluate call, exposed via the provsql.last_eval_method run-time configuration parameter.

Definition at line 117 of file provsql.c.

◆ provsql_mobius

bool provsql_mobius = true

Try the safe-UCQ Möbius-inversion route (a guaranteed-PTIME exact route for its class) BEFORE the joint-width compiler, which it short-circuits on success (on by default); the provsql.mobius GUC is a debug-only switch to disable it.

Definition at line 131 of file provsql.c.

◆ provsql_mobius_max_cnf

int provsql_mobius_max_cnf = 8

Query-cost cap of the Möbius route: it declines when a sentence's CNF has more than this many conjuncts, since the inclusion-exclusion lattice it walks has \(2^M\) elements; ranking / shattering can inflate the conjunct count, which is what raising it buys; provsql.mobius_max_cnf GUC.

Definition at line 133 of file provsql.c.

◆ provsql_mobius_max_gates

int provsql_mobius_max_gates = 4000000

Data-cost cap of the Möbius route: it declines (falling through to joint-width / the ladder) once its compile has built more than this many gates, bounding the \(O(|D|^k)\) blow-up of a high-level safe query on large data; provsql.mobius_max_gates GUC.

Definition at line 132 of file provsql.c.

◆ provsql_monte_carlo_seed

int provsql_monte_carlo_seed = -1

Seed for the Monte Carlo sampler; -1 means non-deterministic (std::random_device); controlled by the provsql.monte_carlo_seed GUC.

Seed for the Monte Carlo sampler, set by the provsql.monte_carlo_seed run-time configuration parameter.

Definition at line 123 of file provsql.c.

◆ provsql_provenance_class

int provsql_provenance_class = PROVSQL_PROVENANCE_SEMIRING
static

Backing variable of the provsql.provenance GUC.

Definition at line 149 of file provsql.c.

◆ provsql_provenance_options

const struct config_enum_entry provsql_provenance_options[]
static
Initial value:
= {
{"where", PROVSQL_PROVENANCE_WHERE, false},
{"semiring", PROVSQL_PROVENANCE_SEMIRING, false},
{"absorptive", PROVSQL_PROVENANCE_ABSORPTIVE, false},
{"boolean", PROVSQL_PROVENANCE_BOOLEAN, false},
{NULL, 0, false}
}
@ PROVSQL_PROVENANCE_WHERE
Universal semiring provenance plus where-provenance gates.
Definition provsql.c:143
@ PROVSQL_PROVENANCE_BOOLEAN
Boolean-only machinery licensed (tagged); implies absorptive.
Definition provsql.c:146
@ PROVSQL_PROVENANCE_SEMIRING
Universal semiring provenance (default).
Definition provsql.c:144
@ PROVSQL_PROVENANCE_ABSORPTIVE
Absorptive-semiring constructions licensed (tagged).
Definition provsql.c:145

Option table of the provsql.provenance GUC.

Definition at line 152 of file provsql.c.

◆ provsql_rv_mc_samples

int provsql_rv_mc_samples = 10000

Default sample count for analytical-evaluator MC fallbacks; 0 disables fallback (callers raise instead); controlled by the provsql.rv_mc_samples GUC.

Default sample count for Monte Carlo fallbacks when an analytical evaluator (Expectation, future hybrid evaluator, ...) cannot decompose a sub-circuit structurally.

Definition at line 124 of file provsql.c.

◆ provsql_simplify_on_load

bool provsql_simplify_on_load = true

Run universal cmp-resolution passes when getGenericCircuit returns; controlled by the provsql.simplify_on_load GUC.

When true (default), every GenericCircuit returned by getGenericCircuit is run through the universal cmp-resolution passes (RangeCheck for now, plus any future passes that decide comparators to certain Boolean values).

Definition at line 134 of file provsql.c.

◆ provsql_stmt_serial

unsigned provsql_stmt_serial = 0

Counts the user's statements, so that a warning a conversion emits at run time is given once for a statement rather than once per row.

Serial of the user's current statement (provsql.c), read by the agg_token conversions to warn once for a statement, not once per row.

Definition at line 224 of file provsql.c.

◆ provsql_subxact_depth

int provsql_subxact_depth[PROVSQL_MAX_SUBXACT_DEPTH]
static

Definition at line 229 of file provsql.c.

◆ provsql_tool_search_path

char* provsql_tool_search_path = NULL

Colon-separated directory list prepended to PATH when invoking external tools (d4, c2d, minic2d, dsharp, weightmc, graph-easy); controlled by the provsql.tool_search_path GUC. Superuser-only (PGC_SUSET): it dictates which directories the postgres OS user searches for executables, so a non-privileged role must not be able to point it at an attacker-controlled binary.

Colon-separated list of directories prepended to PATH when ProvSQL spawns external tools (d4, c2d, minic2d, dsharp, weightmc, graph-easy), set by the provsql.tool_search_path run-time configuration parameter.

Definition at line 120 of file provsql.c.

◆ provsql_transaction_token

char* provsql_transaction_token = NULL

Textual UUID of the update gate standing for the current transaction, or empty; set with SET LOCAL by provsql.transaction_token().

Global variable backing the provsql.transaction_token run-time configuration parameter: the textual UUID of the update gate standing for the current transaction, or empty when it has none yet.

Definition at line 118 of file provsql.c.

◆ provsql_update_provenance

bool provsql_update_provenance = false
static

true when provenance tracking for DML is enabled

Definition at line 112 of file provsql.c.

◆ provsql_verbose

int provsql_verbose = 100

Verbosity level; controlled by the provsql.verbose_level GUC.

Global variable that indicates the verbosity level set by the provsql.verbose_level run-time configuration parameter was set.

Definition at line 113 of file provsql.c.

◆ provsql_where_provenance

bool provsql_where_provenance = false

Global variable that indicates if where-provenance support has been activated through the provsql.where_provenance run-time configuration parameter.

Definition at line 111 of file provsql.c.