![]() |
ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
Implementation of the planner-time UCQ recogniser (descriptor extraction). More...
#include "postgres.h"#include "nodes/parsenodes.h"#include "nodes/nodeFuncs.h"#include "nodes/makefuncs.h"#include "nodes/pg_list.h"#include "catalog/pg_type.h"#include "lib/stringinfo.h"#include "optimizer/clauses.h"#include "parser/parsetree.h"#include "rewrite/rewriteManip.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/ruleutils.h"#include "joint_width_query.h"#include "provsql_utils.h"#include "qual_classify.h"
Go to the source code of this file.
Classes | |
| struct | ColRef |
| A column reference (range-table index, attribute number). More... | |
| struct | ExistCtx |
| Walker context: does any target-list Var reach a tracked atom? More... | |
| struct | RelMerge |
| A merge of relations across the disjuncts of a UCQ: distinct relation OIDs (first-seen order) with their element column-name lists. More... | |
Functions | |
| static int | colref_get (ColRef *cols, int *ncols, Index rtindex, AttrNumber attno) |
| Find-or-add a (rtindex, attno) column node; returns its index. | |
| static int | uf_find (ColRef *cols, int i) |
| Union-find root with path halving. | |
| static void | uf_union (ColRef *cols, int a, int b) |
| static bool | collect_equalities (Node *qual, ColRef *cols, int *ncols, int **pairs, int *npairs, int *const_cols, Const **const_vals, int *nconst) |
Collect the equality structure of a WHERE / ON qual tree, over the shared qual_classify recognisers. | |
| static void | append_json_string (StringInfo buf, const char *s) |
Append s as a JSON string literal (escaping " and \). | |
| static bool | exist_walker (Node *node, void *vctx) |
| static bool | collect_jointree (Node *n, Query *q, Index *atom_rti, Oid *atom_relid, int *natoms, List **qual_list) |
Recursively collect tracked base-relation atoms and the ON quals of a jointree item (a RangeTblRef or an inner JoinExpr). | |
| static int | relmerge_get (RelMerge *m, Oid oid, List *colnames) |
| Find-or-add a relation; returns its global index. | |
| static bool | cq_is_existential (Query *cq, Index *atom_rti, int natoms) |
Does cq expose no tracked-atom variable in its target list (i.e. | |
| static bool | emit_cq_disjunct (const constants_t *constants, Query *cq, RelMerge *m, StringInfo dbuf, const int *head_resno, int n_heads) |
Extract one conjunctive query (a flat join over tracked base relations) as a UCQ disjunct, appending its {"n_vars":N,"atoms":[...]} object to dbuf and registering its relations in m (so atom "rel" indices are global). | |
| static bool | collect_union_arms (Node *node, Query *parent, List **arms) |
| Collect the leaf arm subqueries of a UNION set-operation tree. | |
| static int | union_position_kind (Query *unionq, int resno) |
Classify a UNION output column (1-based resno): is it a per-answer head or a constant projection? | |
| static char * | build_union_descriptor (const constants_t *constants, Query *unionq, const int *head_resno, int n_heads) |
| Build the descriptor for a UNION of conjunctive queries (a UCQ with more than one disjunct): one disjunct per arm, relations merged across arms. | |
| char * | provsql_joint_width_descriptor (const constants_t *constants, Query *q, bool *all_existential, List **head_var_idx, List **head_exprs) |
| Build the joint-width descriptor for a recognised UCQ. | |
Implementation of the planner-time UCQ recogniser (descriptor extraction).
See joint_width_query.h.
Definition in file joint_width_query.c.
|
static |
Append s as a JSON string literal (escaping " and \).
Definition at line 108 of file joint_width_query.c.

|
static |
Build the descriptor for a UNION of conjunctive queries (a UCQ with more than one disjunct): one disjunct per arm, relations merged across arms.
head_resno (length n_heads) gives the per-answer head output positions (canonically numbered in every arm); n_heads == 0 is the Boolean existence case. Returns NULL to decline.
Definition at line 498 of file joint_width_query.c.


|
static |
Collect the equality structure of a WHERE / ON qual tree, over the shared qual_classify recognisers.
Every conjunct of the (AND-only) qual must be either a Var=Var join (its two columns unioned, recorded in pairs) or a Var=Const selection. A selection is recorded in const_cols / const_vals when const_cols is non-NULL (the caller pins the column's variable to the value); when NULL it makes the recogniser decline (the UNION arms, which cannot pin per disjunct, pass NULL). The constant must share the column's exact type: the pin is applied through the gather's text element dictionary, so a cross-type literal could mis-match its column's text form. Any other qual shape declines.
Definition at line 79 of file joint_width_query.c.


|
static |
Recursively collect tracked base-relation atoms and the ON quals of a jointree item (a RangeTblRef or an inner JoinExpr).
Flattens a JOIN b ON ... (and nested inner joins) to the same atom set + equality quals as the comma/WHERE form. Declines (returns false) on an outer join, a non-relation RTE, an untracked relation, or any other item shape.
Definition at line 158 of file joint_width_query.c.


|
static |
Collect the leaf arm subqueries of a UNION set-operation tree.
Walks node (a SetOperationStmt tree); every internal node must be a SETOP_UNION (UNION or UNION ALL – both compute the same Boolean existence), and every leaf a RangeTblRef to an RTE_SUBQUERY arm. Appends each arm Query* to arms. Returns false to decline (INTERSECT / EXCEPT, or an unexpected leaf).
Definition at line 420 of file joint_width_query.c.


|
static |
Find-or-add a (rtindex, attno) column node; returns its index.
Definition at line 36 of file joint_width_query.c.

|
static |
Does cq expose no tracked-atom variable in its target list (i.e.
it computes the Boolean existence of its CQ)?
atom_rti / natoms describe the tracked range-table entries of cq (as collected by collect_jointree).
Definition at line 223 of file joint_width_query.c.


|
static |
Extract one conjunctive query (a flat join over tracked base relations) as a UCQ disjunct, appending its {"n_vars":N,"atoms":[...]} object to dbuf and registering its relations in m (so atom "rel" indices are global).
The per-disjunct variable space is local (variables 0..N-1 of this disjunct); the element dictionary that binds them to data values is shared across the whole UCQ by the gather.
head_resno (length n_heads) gives the arm output-column positions (1-based resno, aligned across the UNION's arms) of the per-answer head variables, in head order. Each is numbered CANONICALLY – head h becomes query variable h in every arm – so a single head_vars = [0,1,…] pins the head in every disjunct (the SQL ucq_joint_provenance_answer uses one head-variable index across all disjuncts). With n_heads == 0 the arm must be Boolean-existential. Returns false to decline.
Definition at line 260 of file joint_width_query.c.


|
static |
Definition at line 131 of file joint_width_query.c.


| char * provsql_joint_width_descriptor | ( | const constants_t * | constants, |
| Query * | q, | ||
| bool * | all_existential, | ||
| List ** | head_var_idx, | ||
| List ** | head_exprs ) |
Build the joint-width descriptor for a recognised UCQ.
Recognises a conjunctive query over provenance-tracked base relations: a flat FROM list (or inner JOIN ... ON tree) of tracked RTE_RELATION entries, a WHERE that is a conjunction of equalities, no HAVING / window functions / sublinks / aggregates other than the provenance aggregation. The variable structure is the column equivalence relation induced by the Var = Var join equalities; a Var = Const selection pins that variable to the literal (the same Sel mechanism as a head). The per-answer heads are the GROUP BY keys (bare tracked columns); the SELECT list itself is arbitrary (a function of the keys), so what is displayed does not constrain recognition.
A UNION [ALL] of such conjunctive queries (the body of an aggregated subquery) is recognised as a genuine multi-disjunct UCQ: one disjunct per arm, relations merged across the arms. Both the Boolean existence and the per-answer form (a free-variable head exposed by every arm and grouped by the outer query) are handled; the head is numbered canonically so a single Sel-pin forces it across all disjuncts.
| constants | Cached extension OIDs. |
| q | The parsed query (read-only). |
| all_existential | Output: set to true iff no variable of the UCQ is exposed in the target list (the query computes the Boolean existence of the UCQ – the #P-hard case the substitution targets); false when output/grouped variables remain (a per-answer query). |
| head_var_idx | Output (may be NULL): when the query is per-answer and every exposed target column is a bare integer Var over a tracked atom, the List of the head variables' query-variable indices (Integer nodes), in output order, deduplicated; NIL if the heads cannot be cleanly extracted (the per-answer substitution then declines). |
| head_exprs | Output (may be NULL): parallel List of the target Var Expr exposing each head variable (the per-group head value at execution). |
ucq_joint_provenance expects), or NULL when q is outside the recogniser's scope. Definition at line 559 of file joint_width_query.c.


|
static |
Find-or-add a relation; returns its global index.
Definition at line 205 of file joint_width_query.c.

|
static |
Union-find root with path halving.
Definition at line 49 of file joint_width_query.c.

|
static |
Definition at line 58 of file joint_width_query.c.


|
static |
Classify a UNION output column (1-based resno): is it a per-answer head or a constant projection?
1 if every arm exposes a bare Var over a tracked base relation there (a real head, pinnable), 0 if every arm exposes a constant / non-tracked expression there (a Boolean projection like SELECT 1, to be ignored), -1 on a mixed or malformed column (the recogniser then declines). Definition at line 452 of file joint_width_query.c.

