pub enum Expr {
Show 19 variants
Column {
qual: Option<String>,
name: String,
},
Literal(Value),
Star,
QualifiedStar(String),
Func {
name: String,
args: Vec<Expr>,
},
Case {
operand: Option<Box<Expr>>,
whens: Vec<(Expr, Expr)>,
else_: Option<Box<Expr>>,
},
Binary {
op: String,
left: Box<Expr>,
right: Box<Expr>,
},
Unary {
op: String,
expr: Box<Expr>,
},
InList {
expr: Box<Expr>,
list: Vec<Expr>,
negated: bool,
},
IsNull {
expr: Box<Expr>,
negated: bool,
},
Cast {
expr: Box<Expr>,
ty: String,
},
Subquery(Box<Select>),
Exists {
query: Box<Select>,
negated: bool,
},
ArrayQuery(Box<Select>),
InSubquery {
expr: Box<Expr>,
query: Box<Select>,
negated: bool,
},
Quantified {
op: String,
left: Box<Expr>,
all: bool,
right: Box<Expr>,
},
Index {
expr: Box<Expr>,
index: Box<Expr>,
},
ArrayLit(Vec<Expr>),
Agg {
name: String,
args: Vec<Expr>,
order_by: Vec<OrderBy>,
distinct: bool,
},
}Variants§
Column
nspname or n.nspname. The qualifier is kept because a join makes
bare names ambiguous, and resolving an ambiguous name by guessing is
how a query silently reads the wrong table’s column.
Literal(Value)
Star
* in count(*), and in a bare select list.
QualifiedStar(String)
alias.*
Func
Case
Both SQL spellings:
simple — CASE x WHEN 'r' THEN 'table' ... ELSE ... END
searched — CASE WHEN x = 'r' THEN 'table' ... ELSE ... END
psql’s \dt uses the simple form with nine branches.
Binary
Unary
InList
x [NOT] IN (a, b, c)
IsNull
x IS [NOT] NULL
Cast
x::type — the cast is PARSED and then ignored at evaluation, because
this engine is dynamically typed. Ignoring it is safe for the shapes
catalogue SQL uses (prattrs::int2[]), and the alternative — refusing
every cast — would reject queries whose result the cast cannot change.
Subquery(Box<Select>)
(SELECT ...) used as a VALUE: one column, at most one row. Postgres’s
\dT hinges on one ((SELECT c.relkind = 'c' FROM pg_class c WHERE c.oid = t.typrelid)), and \d <table> on three.
Exists
[NOT] EXISTS (SELECT ...) — never NULL, which is why it is its own
variant rather than Subquery IS NOT NULL.
ArrayQuery(Box<Select>)
ARRAY(SELECT ...) — the first column of every row, as one array.
\dp, \dT+, \dD and \dy all build one and hand it to
array_to_string.
InSubquery
x [NOT] IN (SELECT ...) — InList semantics over the first column.
Quantified
x op ANY (...) / x op SOME (...) / x op ALL (...). The right side
evaluates to an array — an ArrayQuery when it was written as a
subquery — and op is applied element by element.
Index
arr[i] — one-based, as Postgres subscripts are.
ArrayLit(Vec<Expr>)
ARRAY[a, b, c] — an array literal.
Agg
An aggregate call: count(*), array_agg(x ORDER BY y),
string_agg(DISTINCT s, ',').
A variant of its own rather than a Func whose name happens to be in a
list. “Is this an aggregate?” was a string comparison repeated at five
sites — the select-list check, the pushdown walker, the join-key
walker, the folder and the evaluator — and five copies of one rule is
five chances to disagree about it. It is now a question about SHAPE.
It also carries the two modifiers only an aggregate has, and which
SQLAlchemy’s primary-key reflection depends on:
array_agg(CAST(attname AS TEXT) ORDER BY ord) is meaningless without
the ordering — the array IS the column list, in key order.
Trait Implementations§
impl StructuralPartialEq for Expr
Auto Trait Implementations§
impl Freeze for Expr
impl RefUnwindSafe for Expr
impl Send for Expr
impl Sync for Expr
impl Unpin for Expr
impl UnsafeUnpin for Expr
impl UnwindSafe for Expr
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<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more