Skip to main content

Module coerce

Module coerce 

Source
Expand description

Postgres-semantic value coercion for planner use-sites.

The planner matches sqlparser::ast::Value in numeric contexts (LIMIT, OFFSET, FETCH, fusion weights, …). When a parameter was sent over the pgwire Parse message with Type::UNKNOWN — the default for drivers that don’t pre-fetch OIDs, e.g. postgres-js with fetch_types: false — our bind layer emits it as Value::SingleQuotedString (we have no type information to do otherwise at bind time, and a guess-and-coerce approach would silently corrupt string parameters bound into string columns).

Postgres’ model: UNKNOWN literals stay uncoerced until the planner has context, and the planner then resolves them by the surrounding operator / column type. These helpers are the single chokepoint implementing that resolution for numeric contexts. Any future numeric use-site must route through here — a raw match Value::Number ignores UNKNOWN-coerced literals and re-introduces the silent match-failure bug class.

Row-bound extraction (LIMIT / OFFSET / FETCH) returns Result<RowBound, _>. RowBound has two states: Rows(n) for a literal in [0, usize::MAX], and Unbounded for a NULL argument — PostgreSQL treats NULL as no bound at all, the same as an absent clause. LIMIT ALL is PostgreSQL’s other unbounded spelling, but sqlparser parses it as an absent LIMIT expression, so it never reaches checked_row_bound at all — callers see it as None before this module runs. A malformed literal (negative, fractional, non-numeric, overflowing usize) is a third case: the statement fails. checked_row_bound is the chokepoint every LIMIT/OFFSET/FETCH site calls.

Structs§

InvalidRowBoundLiteral
A row-bound literal that did not resolve to [0, usize::MAX].

Enums§

RowBound
A row bound the planner resolved.

Functions§

as_f64_literal
Resolve a Value into an f64 if numeric-shaped.
as_usize_literal
Resolve a Value into a usize row bound.
checked_row_bound
Resolve a LIMIT/OFFSET/FETCH bound. Names clause and the value as written on failure. Every row-bound site routes through here.
expr_as_usize_literal
Resolve an Expr::Value into a usize row bound. Thin wrapper that unpacks the Expr → Value layer so callers reading LIMIT/OFFSET/FETCH clauses don’t each re-write the unpack. A non-Expr::Value expression (a column reference, a function call, an arithmetic expression) is not a literal the planner can read — it fails with the expression’s Display text as raw.