pub struct TableRef {Show 14 fields
pub name: String,
pub alias: Option<String>,
pub only: bool,
pub as_of_segment: Option<u32>,
pub unnest_expr: Option<Box<Expr>>,
pub unnest_column_aliases: Vec<String>,
pub with_ordinality: bool,
pub generate_series_args: Option<Vec<Expr>>,
pub lateral_subquery: Option<Box<SelectStatement>>,
pub jsonb_each_text_arg: Option<(String, Box<Expr>)>,
pub table_fn_call: Option<Box<(String, Vec<Expr>)>>,
pub scalar_fn_item: bool,
pub rows_from: Option<Vec<(String, Vec<Expr>)>>,
pub json_table: Option<Box<JsonTable>>,
}Fields§
§name: String§alias: Option<String>§only: boolv7.39 (round 644) — FROM ONLY t: do not descend into t’s
children.
The keyword used to be absorbed at parse time, on the reasoning
that SPG’s inheritance children are separate relations a plain
scan does not descend into — so ONLY already described what the
scan did. That stopped being true when a partition parent
started unioning its children: measured, SELECT count(*) FROM ONLY <partitioned parent> answered 2 where PG answers 0.
as_of_segment: Option<u32>v6.10.2 — AS OF SEGMENT '<id>' cold-tier time-travel.
When Some(id), the scan restricts to rows that live in
segment <id> only — useful for forensic inspection of a
specific freezer-emitted segment without exposing the hot
tier. AS OF TIMESTAMP <ts> (PG-flavoured time travel)
is STABILITY carve-out for v6.10 — needs the freezer to
stamp each segment with a wall-clock at creation time.
unnest_expr: Option<Box<Expr>>v7.11.7 — FROM unnest(<expr>) [AS] <alias> set-returning
source. When Some, name is the alias (defaulting to
"unnest" when no AS is given) and the engine builds a
synthetic single-column table by evaluating the expression
once at SELECT entry. Each TEXT[] element becomes one row;
NULL elements become NULL cells. v7.11 supported
uncorrelated UNNEST only as the FROM primary; v7.13.2
(mailrs round-6 S5) widens to UNNEST in any FROM-list
position (cross-join with regular tables).
unnest_column_aliases: Vec<String>v7.13.2 — mailrs round-6 S5. PG-standard
UNNEST(<arr>) AS alias(col_name) column-list aliasing:
when non-empty, the first entry overrides the projected
column name for the unnested column. Empty = fall back to
the table alias (pre-v7.13.2 behaviour).
with_ordinality: boolWITH ORDINALITY on an unnest-channel SRF — when true, the
row-stream gains a trailing BIGINT column counting rows
from 1 in element order. PG names it ordinality; a second
entry in the column-alias list renames it.
generate_series_args: Option<Vec<Expr>>v7.17.0 Phase 3.10 — FROM generate_series(start, stop [, step]) set-returning source. When Some, the engine
materialises a single-column virtual table by stepping
start to stop inclusive. Args are the literal arg list
(2 for default-step, 3 for explicit-step). Supports:
- SmallInt / Int / BigInt with integer step (default = 1)
- Timestamp with INTERVAL step (PG date-range pattern)
Mutually exclusive with
unnest_expr— both populate the same downstream dispatch slot.namedefaults to"generate_series"when no alias is provided.
lateral_subquery: Option<Box<SelectStatement>>v7.17.0 Phase 3.P0-41 — LATERAL ( SELECT … ) derived
table. When Some, the TableRef is a parenthesised SELECT
that may reference columns from the preceding FROM items
(correlated derived table). The executor materialises the
subquery per left-row, substituting outer-column references
against the current join row’s values before running the
inner SELECT, then cross-joins the result back.
Mutually exclusive with name / unnest_expr /
generate_series_args.
jsonb_each_text_arg: Option<(String, Box<Expr>)>v7.37.43-T4.5 — jsonb_each_text(<expr>) set-returning
function as a FROM item. PG semantics: for each key/value
pair in the JSONB object argument, emit one (key TEXT,
value TEXT) row. When prefixed by LATERAL and joined via
CROSS JOIN LATERAL, the argument may reference columns
from a preceding FROM item, in which case the executor
evaluates <expr> per outer row.
Mutually exclusive with unnest_expr / generate_series_args
/ lateral_subquery. The optional LATERAL keyword does not
require a separate flag — the executor evaluates per-row
whenever the join sits in a JoinKind context.
v7.37.17 (17.6 siblings) — the tuple’s first slot carries the
lowercase SRF name (jsonb_each / jsonb_each_text /
json_each / json_each_text) so the executor picks the
value-column rendering (JSON text vs unwrapped text).
table_fn_call: Option<Box<(String, Vec<Expr>)>>v7.39 (read01 partitionfuncs.c) — generic FROM-position table
function channel: (lowercase fn name, args). Carries
pg_partition_tree / pg_partition_ancestors; the executor
dispatches by name.
scalar_fn_item: boolv7.39 (read01 round 78) — this FROM item is a call to a function that
returns a BASE type, so the item’s row type IS that scalar: a whole-row
reference to it yields the value, not a one-field composite
(SELECT j FROM jsonb_array_elements('[1]') AS j → 1, PG). The
desugared shape is indistinguishable from a hand-written
FROM (SELECT unnest(…)) s, which is a subquery and does NOT collapse —
only the parser knows which one it built, so it says so here.
rows_from: Option<Vec<(String, Vec<Expr>)>>v7.39 (read01 round 74) — ROWS FROM (f(a), g(b)): N table functions
zipped in LOCKSTEP, the shorter padded with NULLs (the same rule the
target-list SRFs follow — see round 67). The array-returning family keeps
its own lowering; this channel carries the ones that have no array form
(generate_series, a user RETURNS SETOF function).
json_table: Option<Box<JsonTable>>v7.39 (round 205, JSON_TABLE epic) — a JSON_TABLE(doc, '$path' COLUMNS (...)) FROM item. The doc expr may reference left-side
tables (implicit LATERAL, like every SRF channel). Executed by
walking the row path over the parsed doc, then each column’s
path per row-item; NESTED expands as a per-parent outer join.
Implementations§
Source§impl TableRef
impl TableRef
Sourcepub fn names_a_relation(&self) -> bool
pub fn names_a_relation(&self) -> bool
Whether this FROM item NAMES A RELATION — a table, view or CTE — rather than producing its own rows.
A total destructure, no ... A field added to TableRef is a
compile error here.
v7.40.10, on evidence. This question is asked in 56 places across the engine and every one of them wrote its own list of fields. Exactly one was complete. The others were missing between one and five slots each, and each gap is a defect waiting for the shape that reaches it:
try_stream_single_table's guard named four of seven, so
SELECT * FROM jsonb_each_text('{"a":1}'::jsonb)
ERROR: relation "jsonb_each_text" does not exist
over the extended protocol, while count(*) over the same item
answered and the simple query protocol answered.scalar_fn_item counts as not-a-relation for the same reason the
rest do: the row comes from the item, not from the catalog.
Sourcepub fn kind(&self) -> FromItemKind
pub fn kind(&self) -> FromItemKind
What this FROM item is.
A total destructure, no ... A field added to TableRef is
a compile error here — which is the point, because every
consumer matches exhaustively on the result.
The slots are mutually exclusive by construction: the parser fills exactly one of them, or none for a plain relation.
Sourcepub fn try_for_each_slot_mut<E>(
&mut self,
visit: &mut dyn FnMut(FromSlot<'_>) -> Result<(), E>,
) -> Result<(), E>
pub fn try_for_each_slot_mut<E>( &mut self, visit: &mut dyn FnMut(FromSlot<'_>) -> Result<(), E>, ) -> Result<(), E>
Every expression this FROM item carries, and the SELECT nested in it — in one place, for every pass that needs them.
Written as a TOTAL destructure, with no ... A field added
to TableRef is a compile error here, rather than a defect in
each pass that enumerated the slots for itself. That is the whole
point of the function existing.
v7.40.10, on evidence. TableRef carries seven expression slots
and three separate passes each knew a different subset of them.
In one day: the parameter-substitution walk knew only
lateral_subquery, so unnest($1) reached execution still
holding a placeholder (a customer’s live 500); describe knew
only unnest_expr, so generate_series(…) described no columns
and a driver got a protocol error; and the LIMIT/OFFSET
resolution knew CTEs and UNION peers but not a FROM subquery, so
LIMIT $n inside a derived table returned every row.
Fixing those three one at a time left four slots unvisited. Measured after the third fix shipped, all on the same message:
jsonb_each_text($1) parameter $1 referenced but only 0 bound
ROWS FROM (…$1…) parameter $1 referenced but only 0 bound
json_table($1, …) parameter $1 referenced but only 0 boundThose were the next three reports. This is what stops the fourth.
§Errors
Whatever the callbacks return; the walk stops at the first.