Expand description
Coerce the literals a predicate compares against a declared TIMESTAMP /
TIMESTAMPTZ column into typed instants, once, at plan time.
§Why this exists
A time literal in a WHERE, ON, or WHEN clause reaches the planner as
whatever the user typed: at > 1583402400000, at > '2020-03-05 10:00:00', at > TIMESTAMP '...'. The write side already resolves the
same three spellings to one typed instant through
[super::declared_type_coerce::coerce_value], so every engine stores an
instant. Left as typed, a numeric read literal is an Integer the Data
Plane compares against an instant: the pair has no defined equality or
order, so = never matches and >= either matches nothing or, on a path
that guessed a unit, matches by accident.
Resolving the literal here, against the declared column type the scope
already carries, means the Data Plane only ever compares instants with
instants. It also puts the type error where PostgreSQL puts it: WHERE at = true fails the statement naming the column, instead of scanning every
row to match none.
§Scope
Only TIMESTAMP / TIMESTAMPTZ columns are coerced. Every other declared
type is left as written: the Data Plane’s coerced comparison already
reads "5" against 5 and 1.5 against 1, so no read literal for
those types is lost the way a bare integer against an instant is.
The primary-key column is exempt, mirroring the write side: the engines derive a row’s identity from the literal’s own rendering on both the write and the read side, and re-typing one side would make the row unfindable by the other.
A column the scope does not declare (a schemaless field, a computed alias, an aggregate output) is left untouched: there is no declared type to coerce to.
Functions§
- coerce_
read_ literal - Coerce one literal compared against
columnby the read-side rule.