![]() |
ProvSQL SQL API
Adding support for provenance and uncertainty management to PostgreSQL databases
|
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 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 Comparison operators are placeholders that return | |
| 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 Lives in the Direct calls outside a provenance-tracked query treat each row's contribution unconditionally (no per-row Boolean selector). When the planner hook sees a The internal state is the array of UUIDs of the per-row mixtures. The final function builds a single | |
| 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) |
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.
| 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.
| 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).
| VOID provsql.avg | ( | random_variable | ) |
| 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".
| 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.
| 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.
| CREATE provsql.CAST | ( | UUID AS | random_variable | ) |
| 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.
| 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.probs[i] must be finite, in [0, 1], and the array must sum to 1 within 1e-9.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.
mixture for the Bernoulli-weighted choice constructor. | 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.| 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.| 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).
| 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.
STABLE / IMMUTABLE would collapse two independent draws into one shared gate.| 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.
| 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.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).uniform and exponential below.| VOID provsql.product | ( | random_variable | ) |
| 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.
| 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).
| 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.
| random_variable provsql.random_variable_div | ( | random_variable | a, |
| random_variable | b ) |
random_variable / random_variable (gate_arith DIV).
| BOOLEAN provsql.random_variable_eq | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_eq_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_ge | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_ge_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_gt | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_gt_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| random_variable provsql.random_variable_in | ( | CSTRING | ) |
Input function for the random_variable type.
| BOOLEAN provsql.random_variable_le | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_le_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| BOOLEAN provsql.random_variable_lt | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_lt_random_variable | ( | random_variable | left, |
| random_variable | right ) |
Prefix unary minus on random_variable.
| random_variable provsql.random_variable_make | ( | UUID | tok | ) |
Build a random_variable from a UUID (internal).
| random_variable provsql.random_variable_minus | ( | random_variable | a, |
| random_variable | b ) |
random_variable - random_variable (gate_arith MINUS).
| BOOLEAN provsql.random_variable_ne | ( | random_variable | a, |
| random_variable | b ) |
| BOOLEAN provsql.random_variable_ne_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| random_variable provsql.random_variable_neg | ( | random_variable | a | ) |
Unary -random_variable (gate_arith NEG).
| BOOLEAN provsql.random_variable_op_random_variable | ( | random_variable | left, |
| random_variable | right ) |
| CSTRING provsql.random_variable_out | ( | random_variable | ) |
Output function for the random_variable type.
| random_variable provsql.random_variable_plus | ( | random_variable | a, |
| random_variable | b ) |
random_variable + random_variable (gate_arith PLUS).
| random_variable provsql.random_variable_times | ( | random_variable | a, |
| random_variable | b ) |
random_variable * random_variable (gate_arith TIMES).
| 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.
| 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_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.
| 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_lt | ( | random_variable | a, |
| random_variable | b ) |
| UUID provsql.rv_cmp_ne | ( | random_variable | a, |
| random_variable | b ) |
Build a gate_cmp for a <> b and return its UUID.
| VOID provsql.sum | ( | random_variable | ) |
| 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.
| 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.
| 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).a; the call is silently routed through as_random(a) for the same reason as normal with sigma = 0.