Expand description
Expressions: one enum, its rendering, and the operator chain.
This is the layer bob spreads over its expr/ package. The design differs in
one big way and follows bob closely in another.
The big difference. bob has a struct per shape behind a
bob.Expression interface; keelson has a single Expr enum. Expressions
stay inspectable — which is what Layer 4’s query rewriting needs — there is no
dynamic dispatch on the hot path, Clone is cheap, and all the rendering
decisions sit in one match where they can be read against the grammar.
Expr::Custom holds an erased Expression so a dialect
can add shapes core has never heard of.
The close following. Where the parentheses go, which separator a clause
uses, when a fragment omits itself entirely — that is where bob’s real value
is, and it is reproduced exactly. In particular
Expr::is_atomic/Expr::grouped is bob’s expr.X, the rule that decides
whether an expression is wrapped in parentheses, and it is the single most
output-visible piece of logic in this module.
§Entry points
The free functions here mirror bob’s Builder methods, which means they apply
the parenthesisation rule; the associated constructors on Expr build a node
and nothing more. For the atomic shapes — raw, quote, literal,
arg — the two are the same thing, because the rule leaves those alone.
use keelson_core::expr::{Chain, arg, quote};
let e = quote("age").gte(arg(21i32));
let (sql, args) = keelson_core::build(&Psql, &e)?;
assert_eq!(sql, r#"("age" >= $1)"#);Structs§
- Case
Builder - A
CASEexpression under construction — bob’sCaseChain. - Func
Expr - A function call under construction:
f("row_number", ()).over(window).
Enums§
- Expr
- A SQL expression, as data.
- RawArg
- One replacement for a
?in anExpr::Template.
Traits§
- Chain
- The operator chain:
quote("age").gte(arg(21)). - Into
Expr - Anything that can stand where an expression is expected.
- Into
Expr List - A list of expressions: a tuple, an array, a
Vec,()for none, or a single expression standing for a one-element list. - Into
Ident - The parts of a qualified identifier:
"age", or("users", "id").
Functions§
- and
(a AND b AND c).- arg
- One bound argument, rendered as the dialect’s placeholder.
- arg_
group - Several bound arguments, parenthesised:
($1, $2, $3)— bob’sArgGroup. - args
- Several bound arguments, comma-separated and not parenthesised — for slots
that bring their own parentheses, such as
VALUES (..). - case
- A
CASEexpression. SeeCaseBuilder. - cast
CAST(expr AS type_name).- f
- A function call, optionally windowed:
f("count", "*"),f("row_number", ()).over(w). - group
- A parenthesised, comma-separated list. One element gives plain parentheses.
- literal
- A single-quoted SQL string literal — bob’s
S().literal("A")renders'A'. - named
- A named argument placeholder, for preparing a statement whose values arrive at bind time. Fails on a dialect with no named-argument syntax.
- not
NOT expr.- or
(a OR b OR c).- placeholders
nunbound placeholders, comma-separated — bob’sPlaceholder(n).- quote
- A quoted identifier:
quote("age")gives"age",quote(("users", "id"))gives"users"."id". - raw
- Raw SQL, written verbatim.
?is not rewritten — seetemplate. - template
- Raw SQL with
?placeholders, rewritten into the dialect’s own syntax withargsinterleaved. Write\?for a literal question mark.