ProvSQL SQL API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
Type for continuous random variables

Custom type random_variable: a thin wrapper around a provenance gate UUID, used to expose continuous probabilistic c-tables in SQL. More...

Functions

random_variable provsql.random_variable_in (CSTRING)
 Input function for the random_variable type.
CSTRING provsql.random_variable_out (random_variable)
 Output function for the random_variable type.
random_variable provsql.random_variable_make (UUID tok)
 Build a random_variable from a UUID (internal).
CREATE provsql.CAST (random_variable AS UUID) WITHOUT FUNCTION AS IMPLICIT
 Binary-coercible cast random_variable -> UUID.
CREATE provsql.CAST (UUID AS random_variable) WITHOUT FUNCTION
BOOL provsql.is_finite_float8 (DOUBLE PRECISION x)
 Internal: true iff x is a finite (non-NaN, non-±∞) float8.
random_variable provsql.normal (DOUBLE PRECISION mu, DOUBLE PRECISION sigma)
 Construct a normal-distribution random variable.
random_variable provsql.uniform (DOUBLE PRECISION a, DOUBLE PRECISION b)
 Construct a uniform-distribution random variable on [a, b].
random_variable provsql.exponential (DOUBLE PRECISION lambda)
 Construct an exponential-distribution random variable with rate λ
random_variable provsql.erlang (INTEGER k, DOUBLE PRECISION lambda)
 Construct an Erlang-distribution random variable, sum of k i.i.d.
random_variable provsql.mixture (UUID p, random_variable x, random_variable y)
 Construct a probabilistic-mixture random variable.
random_variable provsql.mixture (DOUBLE PRECISION p_value, random_variable x, random_variable y)
 Ad-hoc mixture constructor that mints a fresh anonymous gate_input Bernoulli with probability p_value.
random_variable provsql.categorical (DOUBLE_PRECISION[] probs, DOUBLE_PRECISION[] outcomes)
 Categorical-RV constructor over explicit (probabilities, values) arrays.
random_variable provsql.as_random (DOUBLE PRECISION c)
 Lift a deterministic constant into a random_variable.
CREATE provsql.CAST (DOUBLE PRECISION AS random_variable) WITH FUNCTION as_random(DOUBLE PRECISION) AS IMPLICIT
 Implicit cast DOUBLE PRECISION -> random_variable (lifts a scalar literal to a constant RV).
random_variable provsql.as_random (INTEGER c)
 as_random for INTEGER (delegates to the float8 form).
random_variable provsql.as_random (NUMERIC c)
 as_random for NUMERIC (delegates to the float8 form).
random_variable provsql.CAST(INTEGER AS RANDOM_VARIABLE) (INTEGER)
 Implicit cast INTEGER -> random_variable.
random_variable provsql.CAST(NUMERIC AS RANDOM_VARIABLE) (NUMERIC)
 Implicit cast NUMERIC -> random_variable.

Arithmetic and comparison on random_variable

Each binary operator below is declared on (random_variable, random_variable) only; mixed shapes such as rv + 2 or 2.5 > rv resolve through the implicit casts from INTEGER / NUMERIC / double precision to random_variable declared above.

This avoids the resolution ambiguity that would arise if both (rv, NUMERIC) and (rv, rv) overloads were declared while implicit casts also existed.

Arithmetic operators build a gate_arith via provenance_arith and return a new random_variable wrapping its UUID.

Comparison operators are placeholders that return BOOLEAN and raise if executed – the BOOLEAN return type is required so that PostgreSQL accepts WHERE rv > 2 at parse-analyze. The planner hook intercepts every such OpExpr (matched by opfuncid against constants_t::OID_FUNCTION_RV_CMP) and rewrites it into a provenance_cmp call whose UUID is conjoined into the tuple's provsql column via provenance_times. Code that needs a gate_cmp UUID directly (without going through the planner hook) uses the rv_cmp_* family below, which call provenance_cmp with the matching float8-comparator OID.

random_variable provsql.random_variable_plus (random_variable a, random_variable b)
 random_variable + random_variable (gate_arith PLUS).
random_variable provsql.random_variable_minus (random_variable a, random_variable b)
 random_variable - random_variable (gate_arith MINUS).
random_variable provsql.random_variable_times (random_variable a, random_variable b)
 random_variable * random_variable (gate_arith TIMES).
random_variable provsql.random_variable_div (random_variable a, random_variable b)
 random_variable / random_variable (gate_arith DIV).
random_variable provsql.random_variable_neg (random_variable a)
 Unary -random_variable (gate_arith NEG).
oid provsql.random_variable_cmp_oid (TEXT sym)
 Internal helper: float8-comparator OID for a given symbol.
BOOLEAN provsql.random_variable_cmp_placeholder (random_variable a, random_variable b)
 Placeholder body shared by every random_variable_* comparison procedure.
BOOLEAN provsql.random_variable_lt (random_variable a, random_variable b)
BOOLEAN provsql.random_variable_le (random_variable a, random_variable b)
BOOLEAN provsql.random_variable_eq (random_variable a, random_variable b)
BOOLEAN provsql.random_variable_ne (random_variable a, random_variable b)
BOOLEAN provsql.random_variable_ge (random_variable a, random_variable b)
BOOLEAN provsql.random_variable_gt (random_variable a, random_variable b)
UUID provsql.rv_cmp_lt (random_variable a, random_variable b)
UUID provsql.rv_cmp_le (random_variable a, random_variable b)
 Build a gate_cmp for a ≤ b and return its UUID.
UUID provsql.rv_cmp_eq (random_variable a, random_variable b)
 Build a gate_cmp for a = b and return its UUID.
UUID provsql.rv_cmp_ne (random_variable a, random_variable b)
 Build a gate_cmp for a <> b and return its UUID.
UUID provsql.rv_cmp_ge (random_variable a, random_variable b)
 Build a gate_cmp for a ≥ b and return its UUID.
UUID provsql.rv_cmp_gt (random_variable a, random_variable b)
 Build a gate_cmp for a > b and return its UUID.
BOOLEAN provsql.random_variable_op_random_variable (random_variable left, random_variable right)
BOOLEAN provsql.random_variable_lt_random_variable (random_variable left, random_variable right)
 Prefix unary minus on random_variable.
BOOLEAN provsql.random_variable_le_random_variable (random_variable left, random_variable right)
BOOLEAN provsql.random_variable_eq_random_variable (random_variable left, random_variable right)
BOOLEAN provsql.random_variable_ne_random_variable (random_variable left, random_variable right)
BOOLEAN provsql.random_variable_ge_random_variable (random_variable left, random_variable right)
BOOLEAN provsql.random_variable_gt_random_variable (random_variable left, random_variable right)

Aggregates over random_variable

Phase 1 of the SUM-over-RV story: an overload of the standard sum aggregate that takes a random_variable per row and returns the random_variable representing the (provenance-weighted) sum.

Lives in the provsql schema so a sum(random_variable) call resolves to it without colliding with the built-in NUMERIC sum overloads in pg_catalog.

Direct calls outside a provenance-tracked query treat each row's contribution unconditionally (no per-row Boolean selector). When the planner hook sees a provsql.sum Aggref over a provenance-tracked query, it wraps the per-row argument x in provsql.mixture(prov_token, x, provsql.as_random(0)) so the aggregate's effective semantics become \(\mathrm{SUM}(x) = \sum_i \mathbf{1}\{\varphi_i\} \cdot X_i\), the natural extension of semimodule-provenance to RV-valued M.

The internal state is the array of UUIDs of the per-row mixtures. The final function builds a single gate_arith PLUS over them (or returns as_random(0) for an empty group, the additive identity). Sharing on provenance_arith's v5 hash means two sum invocations over the same set of rows collide on the same gate.

random_variable provsql.rv_aggregate_semimod (UUID prov, random_variable rv)
 Per-row helper: wrap an RV in mixture(prov, rv, as_random(0)).
UUID[] provsql.sum_rv_sfunc (UUID[] state, random_variable rv)
 State-transition function for sum(random_variable).
random_variable provsql.sum_rv_ffunc (UUID[] state)
 Final function for sum(random_variable): build a gate_arith PLUS root.
VOID provsql.sum (random_variable)
random_variable provsql.avg_rv_ffunc (UUID[] state)
 Final function for avg(random_variable).
VOID provsql.avg (random_variable)
random_variable provsql.product_rv_ffunc (UUID[] state)
 Final function for product(random_variable).
VOID provsql.product (random_variable)

Detailed Description

Custom type random_variable: a thin wrapper around a provenance gate UUID, used to expose continuous probabilistic c-tables in SQL.

The UUID indexes either a gate_rv (an actual distribution) or a gate_value (a zero-variance constant produced by provsql.as_random). Binary-coercible with UUID (same 16-byte layout), so an rv-typed expression flows directly into any function expecting a UUID at zero runtime cost.

Constructors live in this group: provsql.normal(μ, σ), provsql.uniform(a, b), provsql.exponential(λ), provsql.erlang(k, λ), and provsql.as_random(c). Operator overloads (+ - * / and the six comparators) are defined further below, alongside direct rv_cmp_* UUID constructors for callers that want a gate_cmp token without going through the planner hook.

Function Documentation

◆ as_random() [1/3]

random_variable provsql.as_random ( DOUBLE PRECISION c)

Lift a deterministic constant into a random_variable.

Creates a gate_value carrying the constant's TEXT form so that comparisons against a random_variable column produce the same circuit shape regardless of whether the operand is an actual RV or a literal constant.

Marked IMMUTABLE: the gate UUID is derived deterministically from the constant via the same v5 convention as provenance_semimod's inline value gate (concat('value', CAST(c AS VARCHAR))), so as_random(2) always resolves to the same gate, and any other code path that already creates a value gate for the same constant (e.g. provenance_semimod) shares the UUID. create_gate is idempotent on already-mapped tokens, so repeat invocations are harmless.

See also
Wikipedia: Degenerate distribution (Dirac point mass)
Source code
provsql.sql line 2314

◆ as_random() [2/3]

random_variable provsql.as_random ( INTEGER c)

as_random for INTEGER (delegates to the float8 form).

Source code
provsql.sql line 2314

◆ as_random() [3/3]

random_variable provsql.as_random ( NUMERIC c)

as_random for NUMERIC (delegates to the float8 form).

Source code
provsql.sql line 2314

◆ avg()

VOID provsql.avg ( random_variable )

◆ avg_rv_ffunc()

random_variable provsql.avg_rv_ffunc ( UUID[] state)

Final function for avg(random_variable).

Builds the natural lift of "AVG = SUM / COUNT" into the random_variable algebra:

\[ \mathrm{AVG}(x) \;=\; \frac{\sum_i \mathbf{1}\{\varphi_i\} \cdot X_i} {\sum_i \mathbf{1}\{\varphi_i\}} \]

realised as gate_arith(DIV, num, denom) where num is the sum(random_variable) gate over the per-row mixtures and denom is the sum(random_variable) gate over the same provenance gates weighted by a per-row as_random(1) – exactly the SQL pattern "@c sum(x) @c / @c sum(as_random(1))" emitted as a single random_variable token.

Reuses sum_rv_sfunc as the state-transition function so the array of per-row UUIDs is collected identically to sum(random_variable). In a provenance-tracked query the planner-hook rewriter routes RV-returning aggregates through make_rv_aggregate_expression, which wraps each per-row argument in mixture(prov_i, x_i, as_random(0)); the FFUNC then recovers prov_i from each mixture's first child to construct the matching mixture(prov_i, as_random(1), as_random(0)) for the denominator. Outside a tracked query the per-row UUIDs are plain RV roots, in which case each row contributes an unconditional as_random(1) to the denominator – the natural extension of "no provenance = every row counts" used elsewhere in the extension.

Empty group: returns NULL, matching the standard SQL AVG convention. This differs from sum(random_variable), which returns the additive identity as_random(0) for an empty group; for AVG the multiplicative identity is not the right answer and the caller has no way to disambiguate "0 rows" from "rows that sum to 0".

Source code
provsql.sql line 2812

◆ CAST() [1/3]

CREATE provsql.CAST ( DOUBLE PRECISION AS random_variable)

Implicit cast DOUBLE PRECISION -> random_variable (lifts a scalar literal to a constant RV).

Lets users write WHERE reading > 2.5::float8 instead of WHERE reading > provsql.as_random(2.5); the planner-hook rewriter then sees a uniform random_variable on both sides. Sibling casts below cover INTEGER and NUMERIC literals so plain WHERE reading > 2 and WHERE reading > 2.5 also work — PostgreSQL's operator resolution does not chain casts across more than one step, so each NUMERIC-source type needs its own direct cast.

◆ CAST() [2/3]

CREATE provsql.CAST ( random_variable AS UUID)

Binary-coercible cast random_variable -> UUID.

A random_variable is byte-for-byte a pg_uuid_t (alignment char, length 16), so WITHOUT FUNCTION lets PostgreSQL reinterpret the bytes at zero runtime cost. The cast is IMPLICIT so a provsql column or any random_variable expression flows directly into any function expecting a UUID.

◆ CAST() [3/3]

CREATE provsql.CAST ( UUID AS random_variable)

◆ CAST(INTEGER AS RANDOM_VARIABLE)()

random_variable provsql.CAST(INTEGER AS RANDOM_VARIABLE) ( INTEGER )

Implicit cast INTEGER -> random_variable.

Source code
provsql.sql line 2363

◆ CAST(NUMERIC AS RANDOM_VARIABLE)()

random_variable provsql.CAST(NUMERIC AS RANDOM_VARIABLE) ( NUMERIC )

Implicit cast NUMERIC -> random_variable.

Source code
provsql.sql line 2367

◆ categorical()

random_variable provsql.categorical ( DOUBLE_PRECISION[] probs,
DOUBLE_PRECISION[] outcomes )

Categorical-RV constructor over explicit (probabilities, values) arrays.

Builds a categorical-form gate_mixture directly: a fresh gate_input "key" anchor and one gate_mulinput per outcome with positive mass, all sharing the key. The wires [key, mul_1, ..., mul_n] are what downstream evaluators (Expectation, MonteCarloSampler, AnalyticEvaluator, RangeCheck) recognise via isCategoricalMixture and treat as a scalar RV with the categorical distribution probs over outcomes.

Validation:

  • probs and outcomes must be non-null, same length, length ≥ 1.
  • Each probs[i] must be finite, in [0, 1], and the array must sum to 1 within 1e-9.
  • Each outcomes[i] must be finite.

Each call mints a fresh key gate and a fresh set of mulinputs, so two calls to categorical with the same arrays are independent categorical RVs. The marking is VOLATILE accordingly.

Degenerate case: a categorical with exactly one positive-mass outcome reduces to as_random(v) at construction (the block would just be a single mulinput, which is operationally a Dirac point mass). Two such calls share the gate_value UUID via the v5 convention as_random already uses.

See also
mixture for the Bernoulli-weighted choice constructor.
Wikipedia: Categorical distribution
Source code
provsql.sql line 2195

◆ erlang()

random_variable provsql.erlang ( INTEGER k,
DOUBLE PRECISION lambda )

Construct an Erlang-distribution random variable, sum of k i.i.d.

exponentials with shared rate lambda

The Erlang distribution is the sum of k independent Exp(λ) random variables (equivalently the gamma with INTEGER shape). It is the natural closure of i.i.d. exponentials under addition, and is materialised here as a single gate_rv so the analytic CDF and closed-form moments fire directly (rather than the sampler having to draw and sum k exponential leaves per Monte-Carlo iteration).

Validation:

  • k must be ≥ 1. The degenerate k=1 case is silently routed through exponential so erlang(1, λ) shares its gate with exponential(λ).
  • lambda must be finite and strictly positive.
Warning
VOLATILE is load-bearing; see the warning on normal.
See also
Wikipedia: Erlang distribution
Source code
provsql.sql line 2014

◆ exponential()

random_variable provsql.exponential ( DOUBLE PRECISION lambda)

Construct an exponential-distribution random variable with rate λ

Validation:

  • lambda must be finite and strictly positive. No degenerate form exists for the exponential distribution, so there is no silent route through as_random.
Warning
VOLATILE is load-bearing; see the warning on normal.
See also
Wikipedia: Exponential distribution
Source code
provsql.sql line 1972

◆ is_finite_float8()

BOOL provsql.is_finite_float8 ( DOUBLE PRECISION x)

Internal: true iff x is a finite (non-NaN, non-±∞) float8.

PostgreSQL's isnan is defined for NUMERIC only, not for DOUBLE PRECISION; we use the inequality form, which works because PG defines NaN = NaN as TRUE for floats (so NaN <> 'NaN'::float8 is FALSE).

Source code
provsql.sql line 1866

◆ mixture() [1/2]

random_variable provsql.mixture ( DOUBLE PRECISION p_value,
random_variable x,
random_variable y )

Ad-hoc mixture constructor that mints a fresh anonymous gate_input Bernoulli with probability p_value.

Sugar over the mixture(UUID, x, y) form: when the caller doesn't care about reusing the Bernoulli token elsewhere in the circuit (which is the common case — "give me a 0.3 / 0.7 weighted GMM, I don't need to share the coin"), this overload creates the underlying gate_input on the fly with a fresh uuid_generate_v4() token, pins p_value via set_prob, and threads everything into the UUID-keyed constructor.

Each call mints a NEW Bernoulli, so two calls to mixture(0.5, X, Y) are independent mixtures whose branch selections are uncorrelated. When coupling is desired (e.g. two mixtures sharing a coin), use the mixture(UUID, x, y) form with a user-managed gate_input token.

Warning
VOLATILE is load-bearing for the same reason as normal and the other RV constructors – folding under STABLE / IMMUTABLE would collapse two independent draws into one shared gate.
See also
Wikipedia: Mixture distribution
Source code
provsql.sql line 2079

◆ mixture() [2/2]

random_variable provsql.mixture ( UUID p,
random_variable x,
random_variable y )

Construct a probabilistic-mixture random variable.

Returns a random_variable whose distribution is a Bernoulli mixture of two scalar RV roots: with probability P(p = true) the mixture samples x, with the complementary probability it samples y. The mixing token p is a gate_input Bernoulli whose probability has been pinned with set_prob, and the same p can be shared with other branches of the circuit – the Monte-Carlo sampler's per-iteration cache couples every reference to the same draw, so users can build joint conditional structures (e.g. mixture(p, X1, Y1) + mixture(p, X2, Y2) samples X1 + X2 with prob π and Y1 + Y2 with prob 1-π).

x and y may be any scalar RV root: a base gate_rv (normal / uniform / exponential / erlang), a gate_value Dirac (as_random), a gate_arith expression, or another mixture. N-ary mixtures are built by composition – mixture(p1, A, mixture(p2, B, C)) realises a 3-component mixture with effective weights π1, (1-π1)·π2, (1-π1)·(1-π2).

Validation:

  • p must point to a Boolean gate (input, mulinput, update, plus, times, monus, project, eq, cmp, zero, one). Compound Boolean gates derive their probability from their atoms via the active probability-evaluation method; a bare gate_input's probability is whatever set_prob pinned (set_prob is responsible for keeping it in [0, 1]).
  • x and y must be scalar RV roots; aggregate / Boolean roots are rejected at construction.

Two calls to mixture with the same (p, x, y) operands collapse to the same gate_mixture node by v5-hash, exactly like arith(PLUS, X, Y). Draw independence is controlled by p: sharing p couples branch selection across consumers via the sampler's bool_cache_; minting independent Bernoullis (e.g. via the mixture(p_value, …) overload) decouples them.

See also
Wikipedia: Mixture distribution
Source code
provsql.sql line 2079

◆ normal()

random_variable provsql.normal ( DOUBLE PRECISION mu,
DOUBLE PRECISION sigma )

Construct a normal-distribution random variable.

Creates a fresh gate_rv with "normal:μ,σ" stored in the gate's extra field, and returns a random_variable pointing at it.

Validation:

  • mu and sigma must be finite (no NaN, no ±Infinity).
  • sigma must be non-negative.
  • When sigma is zero the distribution degenerates to the Dirac at mu; the call is silently routed through as_random(mu), producing a gate_value rather than a zero-variance gate_rv. This keeps the sampler / moment / boundcheck paths free of σ=0 special cases and lets normal(x, 0) share its gate with as_random(x).
Warning
The VOLATILE marking is load-bearing and must not be weakened. Each call mints a fresh uuid_generate_v4 token because two calls to normal(0, 1) are independent random variables; if PostgreSQL were allowed to fold the function (which it would under STABLE / IMMUTABLE), two calls in the same query would share a UUID and collapse into a single dependent RV, silently breaking the c-table semantics. Same warning applies to uniform and exponential below.
See also
Wikipedia: Normal distribution
Source code
provsql.sql line 1900

◆ product()

VOID provsql.product ( random_variable )

◆ product_rv_ffunc()

random_variable provsql.product_rv_ffunc ( UUID[] state)

Final function for product(random_variable).

Multiplicative analogue of sum(random_variable):

\[ \mathrm{PRODUCT}(x) \;=\; \prod_i \big(\mathbf{1}\{\varphi_i\} \cdot X_i + \mathbf{1}\{\neg\varphi_i\} \cdot 1\big) \;=\; \prod_{i : \varphi_i} X_i \]

realised as gate_arith(TIMES, mixtures) over per-row contributions whose else-branch is as_random(1) (the multiplicative identity), so rows whose provenance is false contribute 1 to the product instead of 0.

The C-side wrap shared with sum / avg always builds mixture(prov_i, X_i, as_random(0)); the PRODUCT FFUNC patches each mixture's else-branch to as_random(1) by reconstructing the mixture with the corrected else-arg. Going through provsql.mixture (rather than create_gate directly) keeps the gate v5-hash consistent with any other mixture sharing the same (prov_i, X_i, as_random(1)) triple.

Reuses sum_rv_sfunc as the state-transition function. Empty group: returns the multiplicative identity as_random(1) – the natural counterpart to sum(random_variable)'s empty-group as_random(0).

Singleton group: returns the single patched child directly without minting a useless single-child gate_arith TIMES root.

Direct (untracked) call: state entries are raw RV uuids rather than mixtures; pass them through unchanged so PRODUCT degenerates to the straight RV product over all rows, the natural "no provenance = every row counts" behaviour.

Source code
provsql.sql line 2909

◆ random_variable_cmp_oid()

oid provsql.random_variable_cmp_oid ( TEXT sym)

Internal helper: float8-comparator OID for a given symbol.

Wraps the '<sym>(DOUBLE PRECISION,DOUBLE PRECISION)'::regoperator lookup so the per-comparator functions read uniformly. Marked IMMUTABLE because the resolved OID is fixed at catalog level (the float8 comparators are core PG and never re-installed).

Source code
provsql.sql line 2465

◆ random_variable_cmp_placeholder()

BOOLEAN provsql.random_variable_cmp_placeholder ( random_variable a,
random_variable b )

Placeholder body shared by every random_variable_* comparison procedure.

Raises with a uniform message.

Source code
provsql.sql line 2485

◆ random_variable_div()

random_variable provsql.random_variable_div ( random_variable a,
random_variable b )

random_variable / random_variable (gate_arith DIV).

Source code
provsql.sql line 2436

◆ random_variable_eq()

BOOLEAN provsql.random_variable_eq ( random_variable a,
random_variable b )

◆ random_variable_eq_random_variable()

BOOLEAN provsql.random_variable_eq_random_variable ( random_variable left,
random_variable right )

◆ random_variable_ge()

BOOLEAN provsql.random_variable_ge ( random_variable a,
random_variable b )

◆ random_variable_ge_random_variable()

BOOLEAN provsql.random_variable_ge_random_variable ( random_variable left,
random_variable right )

◆ random_variable_gt()

BOOLEAN provsql.random_variable_gt ( random_variable a,
random_variable b )

◆ random_variable_gt_random_variable()

BOOLEAN provsql.random_variable_gt_random_variable ( random_variable left,
random_variable right )

◆ random_variable_in()

random_variable provsql.random_variable_in ( CSTRING )

Input function for the random_variable type.

Source code
provsql.sql line 1828

◆ random_variable_le()

BOOLEAN provsql.random_variable_le ( random_variable a,
random_variable b )

◆ random_variable_le_random_variable()

BOOLEAN provsql.random_variable_le_random_variable ( random_variable left,
random_variable right )

◆ random_variable_lt()

BOOLEAN provsql.random_variable_lt ( random_variable a,
random_variable b )

◆ random_variable_lt_random_variable()

BOOLEAN provsql.random_variable_lt_random_variable ( random_variable left,
random_variable right )

Prefix unary minus on random_variable.

Source code
provsql.sql line 2622

◆ random_variable_make()

random_variable provsql.random_variable_make ( UUID tok)

Build a random_variable from a UUID (internal).

Source code
provsql.sql line 1845

◆ random_variable_minus()

random_variable provsql.random_variable_minus ( random_variable a,
random_variable b )

random_variable - random_variable (gate_arith MINUS).

Source code
provsql.sql line 2412

◆ random_variable_ne()

BOOLEAN provsql.random_variable_ne ( random_variable a,
random_variable b )

◆ random_variable_ne_random_variable()

BOOLEAN provsql.random_variable_ne_random_variable ( random_variable left,
random_variable right )

◆ random_variable_neg()

random_variable provsql.random_variable_neg ( random_variable a)

Unary -random_variable (gate_arith NEG).

Source code
provsql.sql line 2448

◆ random_variable_op_random_variable()

BOOLEAN provsql.random_variable_op_random_variable ( random_variable left,
random_variable right )

◆ random_variable_out()

CSTRING provsql.random_variable_out ( random_variable )

Output function for the random_variable type.

Source code
provsql.sql line 1833

◆ random_variable_plus()

random_variable provsql.random_variable_plus ( random_variable a,
random_variable b )

random_variable + random_variable (gate_arith PLUS).

Source code
provsql.sql line 2400

◆ random_variable_times()

random_variable provsql.random_variable_times ( random_variable a,
random_variable b )

random_variable * random_variable (gate_arith TIMES).

Source code
provsql.sql line 2424

◆ rv_aggregate_semimod()

random_variable provsql.rv_aggregate_semimod ( UUID prov,
random_variable rv )

Per-row helper: wrap an RV in mixture(prov, rv, as_random(0)).

Internal helper used by the planner-hook rewriter to lift a sum(random_variable) argument into its provenance-aware form. Encodes one row's contribution to the SUM as a Bernoulli mixture over the row's provenance: with probability P(prov) the mixture samples rv, otherwise it samples the additive identity as_random(0). Exposed as a regular SQL function so the planner can construct a FuncExpr by name without needing to disambiguate mixture / as_random overloads at OID-lookup time.

Source code
provsql.sql line 2713

◆ rv_cmp_eq()

UUID provsql.rv_cmp_eq ( random_variable a,
random_variable b )

Build a gate_cmp for a = b and return its UUID.

Source code
provsql.sql line 2551

◆ rv_cmp_ge()

UUID provsql.rv_cmp_ge ( random_variable a,
random_variable b )

Build a gate_cmp for a ≥ b and return its UUID.

Source code
provsql.sql line 2571

◆ rv_cmp_gt()

UUID provsql.rv_cmp_gt ( random_variable a,
random_variable b )

Build a gate_cmp for a > b and return its UUID.

Source code
provsql.sql line 2581

◆ rv_cmp_le()

UUID provsql.rv_cmp_le ( random_variable a,
random_variable b )

Build a gate_cmp for a ≤ b and return its UUID.

Source code
provsql.sql line 2541

◆ rv_cmp_lt()

UUID provsql.rv_cmp_lt ( random_variable a,
random_variable b )

◆ rv_cmp_ne()

UUID provsql.rv_cmp_ne ( random_variable a,
random_variable b )

Build a gate_cmp for a <> b and return its UUID.

Source code
provsql.sql line 2561

◆ sum()

VOID provsql.sum ( random_variable )

◆ sum_rv_ffunc()

random_variable provsql.sum_rv_ffunc ( UUID[] state)

Final function for sum(random_variable): build a gate_arith PLUS root.

Empty group (state = '{}'): return as_random(0), the additive identity, so SUM over zero rows is the deterministic scalar 0 – matches the AGG_TOKEN convention in agg_raw_moment.

Singleton group: return the single child directly without minting a useless single-child gate_arith.

Otherwise: build gate_arith(PLUS, state) via provenance_arith.

Source code
provsql.sql line 2752

◆ sum_rv_sfunc()

UUID[] provsql.sum_rv_sfunc ( UUID[] state,
random_variable rv )

State-transition function for sum(random_variable).

Appends the input RV's UUID to the running array. NULL inputs are skipped (matching standard SUM semantics). The aggregate's INITCOND is '{}' so the FINALFUNC always runs even on an empty group, which is what lets us return as_random(0) (the additive identity) for an empty SUM rather than NULL.

Source code
provsql.sql line 2729

◆ uniform()

random_variable provsql.uniform ( DOUBLE PRECISION a,
DOUBLE PRECISION b )

Construct a uniform-distribution random variable on [a, b].

Validation:

  • a and b must be finite.
  • a must be ≤ b (reversed bounds are rejected).
  • When a = b the distribution is the Dirac at a; the call is silently routed through as_random(a) for the same reason as normal with sigma = 0.
Warning
VOLATILE is load-bearing; see the warning on normal.
See also
Wikipedia: Continuous uniform distribution
Source code
provsql.sql line 1937