ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
safe_query.h
Go to the documentation of this file.
1/**
2 * @file safe_query.h
3 * @brief Public surface of the safe-query (hierarchical-CQ) rewriter.
4 *
5 * The implementation lives in @c safe_query.c. ProvSQL's main planner
6 * hook (@c process_query in @c provsql.c) calls @c try_safe_query_rewrite
7 * between the AGG-DISTINCT rewrite and @c get_provenance_attributes,
8 * but only when the @c provsql.boolean_provenance GUC is on. Returning
9 * a non-NULL @c Query feeds the rewriter's output back through
10 * @c process_query from the top; returning @c NULL makes the caller
11 * fall through to the existing pipeline.
12 */
13#ifndef SAFE_QUERY_H
14#define SAFE_QUERY_H
15
16#include "postgres.h"
17#include "nodes/parsenodes.h"
18
19#include "provsql_utils.h"
20
21/** @brief GUC: opt-in safe-query optimisation, declared in @c provsql.c. */
23
24/**
25 * @brief Top-level entry point for the hierarchical-CQ rewriter.
26 *
27 * Runs the shape gate, then the hierarchy detector. When both accept,
28 * applies the rewrite and returns the rewritten @c Query (the caller
29 * is expected to re-enter @c process_query on the result). Returns
30 * @c NULL when @p q is outside the safe-query scope.
31 *
32 * @param constants Cached extension OIDs (from @c get_constants).
33 * @param q Input @c Query, modified in place by side-effect-free
34 * helpers but @em not consumed; the rewriter
35 * @c copyObject's it before mutating.
36 * @return A fresh rewritten @c Query, or @c NULL to fall through.
37 */
38extern Query *try_safe_query_rewrite(const constants_t *constants, Query *q);
39
40/**
41 * @brief Per-atom marker spec for the inversion-free path.
42 *
43 * One entry per range-table atom (indexed by @c relid-1). When @c valid, the
44 * planner wraps that atom's provenance token in
45 * @c annotate(prov, inversion_free_key(root_col, sec_col, factor)): a
46 * per-input order key built from the tuple's root- and secondary-class column
47 * values and its factor (@c SAFE_CERT_GUARD_FACTOR for the shared self-join
48 * guard, else a per-factor id).
49 */
50typedef struct InvFreeMarker {
51 bool valid;
52 AttrNumber root_col; /* 1-based root-class column */
53 AttrNumber sec_col; /* 1-based secondary-class column */
54 int factor; /* SAFE_CERT_GUARD_FACTOR, or a factor id */
56
57/**
58 * @brief Per-query marker context for the inversion-free path, threaded through
59 * the recursive query rewrite to reach base inputs nested in subqueries.
60 *
61 * The detector runs on a *flattened* copy of the lineage query (single-base SPJ
62 * subqueries / views inlined to their base relation in place, so range-table
63 * positions are preserved). The resulting per-atom markers are organised into
64 * a context tree mirroring the *original* (un-flattened) query: for range-table
65 * position @c i (0-based), @c markers[i] is the order marker for a base relation
66 * sitting directly at @c i, while @c sub[i] is the child context for a flattened
67 * subquery at @c i (whose own base atom carries the marker). Exactly one of
68 * @c markers[i].valid and @c sub[i]!=NULL holds for a certified atom. A query
69 * rewritten with a non-NULL context applies @c markers to its own base prov
70 * Vars and passes @c sub[i] down when recursing into the subquery at @c i.
71 */
74 int natoms; /* this query's range-table length */
75 InvFreeMarker *markers; /* size natoms: direct base-atom markers */
76 InvFreeMarkerCtx **sub; /* size natoms: child ctx per flattened subquery, or NULL */
77};
78
79/**
80 * @brief Inversion-free analysis of the lineage query @p q.
81 *
82 * Runs the detector on @p q itself (the query whose provenance lineage is being
83 * built), so the certificate and the per-atom marker specs align with the
84 * lineage by construction, independent of any read-once pre-pass. On success
85 * sets @p cert_out to a palloc'd @c C-prefixed serialised @c SafeCert recipe
86 * (for the per-row root) and, when the marker model applies, @p markers_out to
87 * a palloc'd array of @c *natoms_out @c InvFreeMarker (one per atom); otherwise
88 * leaves them @c NULL.
89 *
90 * @return @c true if @p q is certified inversion-free (cert produced).
91 */
92extern bool inversion_free_analyze(const constants_t *constants, Query *q,
93 char **cert_out, InvFreeMarker **markers_out,
94 int *natoms_out);
95
96/**
97 * @brief PG 18 helper: strip the synthetic @c RTE_GROUP entry from
98 * @p q in place, resolving every grouped @c Var back to its
99 * base-table expression. Defined in @c provsql.c.
100 *
101 * Idempotent: a no-op on earlier PostgreSQL versions and when
102 * @c q->hasGroupRTE is already false. The safe-query rewriter
103 * applies it before the union-find pass so the range table is flat.
104 */
105extern void strip_group_rte_pg18(Query *q);
106
107#endif /* SAFE_QUERY_H */
bool provsql_boolean_provenance
Derived flag: the session's provenance class is 'boolean' – enables the Boolean-only machinery (safe-...
Definition provsql.c:107
Core types, constants, and utilities shared across ProvSQL.
Query * try_safe_query_rewrite(const constants_t *constants, Query *q)
Top-level entry point for the hierarchical-CQ rewriter.
bool inversion_free_analyze(const constants_t *constants, Query *q, char **cert_out, InvFreeMarker **markers_out, int *natoms_out)
Inversion-free analysis of the lineage query q.
void strip_group_rte_pg18(Query *q)
PG 18 helper: strip the synthetic RTE_GROUP entry from q in place, resolving every grouped Var back t...
Per-query marker context for the inversion-free path, threaded through the recursive query rewrite to...
Definition safe_query.h:73
InvFreeMarkerCtx ** sub
Definition safe_query.h:76
InvFreeMarker * markers
Definition safe_query.h:75
Per-atom marker spec for the inversion-free path.
Definition safe_query.h:50
AttrNumber sec_col
Definition safe_query.h:53
AttrNumber root_col
Definition safe_query.h:52
Structure to store the value of various constants.