Expand description
Prepared-statement parameter binding (SQLR-23).
Two responsibilities:
-
Placeholder rewriting at prepare time. The user writes
?in the SQL; sqlparser parses each asExpr::Value(Placeholder("?")). We walk the parsed AST left-to-right and rewrite each bare?to?N(1-indexed source order) so the later substitution pass knows which slot to bind. The rewritten AST is whatStatementcaches. -
Substitution at execute time. Given the cached AST and a
&[Value]slice, walk a clone of the AST and replace everyExpr::Value(Placeholder("?N"))with the matchingparams[N-1].
Substitution lowers the bound value into a node shape the rest of the pipeline already understands:
- Scalars (
Integer,Real,Text,Bool,Null) becomeExpr::Value(...)literals — same shape an inline literal would parse to. Existing executor / parser arms handle them unchanged. - Vectors become
Expr::Identifier { quote_style: Some('['), value: "<csv>" }, which is the in-band form sqlparser produces for inline bracket-array literals like[0.1, 0.2, ...]. The INSERT parser, the executor’seval_expr_scope, and the HNSW probe optimizer all already recognize that shape, so a boundValue::Vector(...)flows through every path that an inline[...]literal does — including the HNSW shortcut.
Doing it as an AST-rewrite (rather than threading &[Value] through
the executor) keeps the diff focused: every existing executor arm
sees concrete literals, exactly as it does today on inline-params SQL.
Functions§
- rewrite_
placeholders - Walks every expression in
stmtand rewrites bare?placeholders to?N(1-indexed source order). Returns the total parameter count. - substitute_
params - Substitutes every
?Nplaceholder instmtwith the matching value fromparams. Mutates the AST in place — callers should clone first if they want the original back.