pub struct Select<X: Extension = NoExt> {Show 17 fields
pub distinct: Option<SelectDistinct<X>>,
pub straight_join: bool,
pub projection: ThinVec<SelectItem<X>>,
pub into: Option<Box<IntoTarget>>,
pub from: ThinVec<TableWithJoins<X>>,
pub lateral_views: ThinVec<LateralView<X>>,
pub selection: Option<Expr<X>>,
pub connect_by: Option<Box<HierarchicalClause<X>>>,
pub group_by: ThinVec<GroupByItem<X>>,
pub group_by_quantifier: Option<SetQuantifier>,
pub group_by_all: Option<GroupByAllSpelling>,
pub having: Option<Expr<X>>,
pub windows: ThinVec<NamedWindow<X>>,
pub qualify: Option<Box<Expr<X>>>,
pub sample: Option<Box<SampleClause>>,
pub spelling: SelectSpelling,
pub meta: Meta,
}Expand description
An SQL select.
Fields§
§distinct: Option<SelectDistinct<X>>The ALL / DISTINCT / DISTINCT ON (...) set quantifier, or None when
the SELECT writes no quantifier (the implicit ALL).
straight_join: boolMySQL’s SELECT STRAIGHT_JOIN ... modifier — the query-wide form of the
JoinOperator::Inner straight join-order hint, written after the
DISTINCT/ALL quantifier. A flag (not a node) because it is a surface
modifier that rides Select exactly as distinct does; only MySQL parses it
(gated by JoinSyntax::straight_join).
projection: ThinVec<SelectItem<X>>projection in source order.
into: Option<Box<IntoTarget>>PostgreSQL’s SELECT … INTO <table> create-table target, written between the
projection and FROM; None for every standard SELECT. Boxed because the
clause is rare (gated to PostgreSQL via
SelectSyntax::select_into) while Select is
a hot node, so the common case pays one pointer, not the inline
target. This is the materialize-into-a-new-table form; the SQL-standard
SELECT … INTO <variable> (PSM host/local-variable assignment) is a different
construct and is deliberately not modelled here.
from: ThinVec<TableWithJoins<X>>from in source order.
lateral_views: ThinVec<LateralView<X>>Hive/Spark LATERAL VIEW [OUTER] explode(col) t AS a, b generator clauses,
written after the whole FROM clause and before WHERE, each cross-joining the
rows a table-generating function produces; empty for every SELECT that writes
none. See LateralView. Gated by
SelectSyntax::lateral_view_clause — on for
Hive/Databricks/Lenient, so the field stays empty elsewhere. A ThinVec because
the clause is repeatable and rare while Select is a hot node: the empty vector
is one pointer (the Query::pipe_operators precedent), so the common case
pays one word.
selection: Option<Expr<X>>Predicate that filters input rows.
connect_by: Option<Box<HierarchicalClause<X>>>The Oracle-style [START WITH <cond>] CONNECT BY [NOCYCLE] <cond> hierarchical
query clause, written after WHERE and before GROUP BY; None for every
SELECT that writes none. See HierarchicalClause. Gated by
SelectSyntax::connect_by_clause — on for
Snowflake and the Lenient union, so the field stays None elsewhere.
Option<Box<…>> because the clause is rare while Select is a hot node: the
common (absent) case is one null pointer (the Select::into precedent), and
boxing the whole START WITH/CONNECT BY pair keeps both of its inline Exprs
off the Select footprint.
group_by: ThinVec<GroupByItem<X>>The GROUP BY list. Each item is a GroupByItem: an ordinary grouping
expression or one of the SQL:1999 grouping-set constructs
(ROLLUP/CUBE/GROUPING SETS/empty ()), which PostgreSQL lowers in this
position and are therefore their own grammar node rather than
FunctionCall expressions.
group_by_quantifier: Option<SetQuantifier>PostgreSQL’s GROUP BY {DISTINCT | ALL} <grouping items> set-quantifier
(SQL:2016 feature T434): a quantifier on the whole grouping clause that
governs deduplication of the grouping sets the items generate — DISTINCT
collapses duplicate sets, ALL (the default) keeps them. None when the
clause writes no quantifier; Some(SetQuantifier::All) /
Some(SetQuantifier::Distinct) record the explicit spelling so rendering
round-trips it (the Select::distinct precedent for the projection
quantifier). The quantifier prefixes the group_by list and
requires it to be non-empty — PostgreSQL rejects a bare GROUP BY ALL /
GROUP BY DISTINCT (verified on pg_query PG-17), which is exactly what keeps it
MECE with group_by_all: this quantifier is ALL as a
modifier of a non-empty item list, whereas DuckDB’s GROUP BY ALL mode is
ALL standing alone as the entire clause (empty item list). Gated by
GroupingSyntax::group_by_set_quantifier.
group_by_all: Option<GroupByAllSpelling>DuckDB’s GROUP BY ALL mode: group by every non-aggregated projection
column, resolved at bind time. A flag with an empty
group_by list rather than a GroupByItem variant
because ALL is a mode of the whole clause, never one grouping item —
DuckDB rejects mixing it with explicit keys or grouping sets (GROUP BY ALL, x / GROUP BY ROLLUP(x), ALL are syntax errors; probed on 1.5.4) —
and the key list is unknowable at parse time, so a synthetic item would be
a lie (the resolved shape decision). DuckDB’s own tree
corroborates the mode framing: GROUP BY ALL serializes as
aggregate_handling: FORCE_AGGREGATES with empty group_expressions. A
bare flag like straight_join; the parser never
sets it alongside a non-empty group_by. None when the clause writes no
ALL mode; Some(_) records which surface spelling opened it — DuckDB writes
the mode two interchangeable ways, the keyword GROUP BY ALL and the
shorthand GROUP BY * (both bind to “group by every non-aggregated projection
column”; * is bare-only, DuckDB rejects GROUP BY *, x — probed on 1.5.4),
so the spelling is data the renderer round-trips (the GroupByAllSpelling
tag) rather than a normalized flag. Gated by
GroupingSyntax::group_by_all.
having: Option<Expr<X>>Predicate applied after grouping.
windows: ThinVec<NamedWindow<X>>windows in source order.
qualify: Option<Box<Expr<X>>>DuckDB’s QUALIFY <predicate> clause: a filter over window-function results,
applied after grouping. A distinct slot rather than a spelling of HAVING
(which filters groups) because the two have different semantics; QUALIFY is a
common cross-dialect extension (Teradata-origin; Snowflake/BigQuery/DuckDB), so
this is the common shape anchored where the standard is silent. Sits
after windows because DuckDB’s grammar places the clause
after the WINDOW clause (… HAVING … WINDOW … QUALIFY …; QUALIFY … WINDOW …
is a DuckDB syntax error — verified against DuckDB 1.5.4). Boxed because the
clause is rare (gated to DuckDB via
SelectSyntax::qualify) while Select is a
hot node, so the common case pays one pointer (the
into precedent). Whether the predicate references a window
function is a bind-time check (DuckDB: “at least one window function must
appear…”), past the parse-level contract — the parser accepts any expression.
sample: Option<Box<SampleClause>>DuckDB’s USING SAMPLE <entry> query-level sample clause, written after
qualify and before the enclosing query’s ORDER BY
(… QUALIFY … USING SAMPLE 3 ORDER BY …; the reverse order is a DuckDB syntax
error, verified against 1.5.4). Boxed because the clause is rare (gated to
DuckDB via QueryTailSyntax::using_sample) while
Select is a hot node, so the common case pays one pointer (the
qualify/into precedent). None when unwritten.
spelling: SelectSpellingThe surface syntax that produced this SELECT body — an ordinary SELECT …
or the TABLE <name> short form. Kept as data so the renderer round-trips the
written spelling (the LimitSyntax precedent).
meta: MetaSource location and node identity.
Trait Implementations§
Source§impl<'de, X> Deserialize<'de> for Select<X>where
X: Deserialize<'de> + Extension,
impl<'de, X> Deserialize<'de> for Select<X>where
X: Deserialize<'de> + Extension,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl<X: Eq + Extension> Eq for Select<X>
Source§impl<X: Extension + Render> Render for Select<X>
impl<X: Extension + Render> Render for Select<X>
Source§fn render(&self, ctx: &RenderCtx<'_>, f: &mut Formatter<'_>) -> Result
fn render(&self, ctx: &RenderCtx<'_>, f: &mut Formatter<'_>) -> Result
Source§fn operand_binding_power(&self) -> Option<BindingPower>
fn operand_binding_power(&self) -> Option<BindingPower>
None (the default) for a self-delimiting node — an atom, call, or
constructor — that never needs parentheses. Read moreimpl<X: PartialEq + Extension> StructuralPartialEq for Select<X>
Auto Trait Implementations§
impl<X> Freeze for Select<X>where
X: Freeze,
impl<X> RefUnwindSafe for Select<X>where
X: RefUnwindSafe,
impl<X> Send for Select<X>where
X: Send,
impl<X> Sync for Select<X>where
X: Sync,
impl<X> Unpin for Select<X>where
X: Unpin,
impl<X> UnsafeUnpin for Select<X>where
X: UnsafeUnpin,
impl<X> UnwindSafe for Select<X>where
X: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> DynAstExt for T
impl<T> DynAstExt for T
Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&dyn Any for downcasting a node back to its concrete type.Source§fn dyn_clone(&self) -> Box<dyn DynAstExt>
fn dyn_clone(&self) -> Box<dyn DynAstExt>
Clone (whose
Self-returning signature cannot go through a vtable).Source§fn dyn_eq(&self, other: &dyn DynAstExt) -> bool
fn dyn_eq(&self, other: &dyn DynAstExt) -> bool
PartialEq (whose &Self argument cannot go through a vtable). Equal
iff other holds the same concrete type and that type deems the values
equal; differently-typed nodes are never equal.