pub enum Expr {
Column(ColumnBinding),
Constant(ValueRef),
Cast {
input: ExprRef,
try_cast: bool,
},
Compare {
op: CompareOp,
left: ExprRef,
right: ExprRef,
},
Conjunction {
op: ConjunctionOp,
children: Slice,
},
Function {
name: StrRef,
args: Slice,
},
Aggregate {
name: StrRef,
args: Slice,
distinct: bool,
filter: Option<ExprRef>,
},
Case {
arms: Slice,
otherwise: Option<ExprRef>,
},
}Expand description
One bound expression.
The type of an expression is not in here. It lives in a parallel vector in Plan, indexed by
the same ExprRef, because a LogicalType owns a Vec for its nested cases and putting
one inside every variant would make the common variants three times larger for the benefit of
the rare ones.
Variants§
Column(ColumnBinding)
A reference to a column of some operator’s output.
Constant(ValueRef)
A literal, folded constant, or bound parameter value.
Cast
A cast to the expression’s own type.
The target is the type stored for this expression, not a second copy of it, so there is no way for a cast to disagree with its own result type.
Fields
Compare
A binary comparison.
Conjunction
An AND or OR over two or more operands.
Flat rather than binary, because filter pushdown splits a conjunction into its parts and a
right-leaning tree of two-argument ANDs makes that a recursion instead of a loop.
Fields
op: ConjunctionOpWhich connective.
Function
A scalar function, already resolved to one overload by the binder.
The name is the resolved function’s name and not the name the user wrote, so a + b is a
call to + and an alias in the catalog has already been followed.
Fields
Aggregate
An aggregate function.
An aggregate appears only as a direct element of Node::Aggregate’s aggregate list.
Anything downstream that wants the result refers to it with a ColumnBinding into the
aggregate’s table index, which is why that node has one. Plan::validate checks this,
and the textual form relies on it: an aggregate and a scalar function print the same way,
and it is the slot they are printed in that says which is which.
Fields
Case
A searched CASE.
There is no simple CASE here. CASE x WHEN 1 THEN ... is rewritten to the searched form
by the binder, because two representations of one thing is two code paths in every pass
that touches either.