WHERE expressions: wire into update/delete/show data + SQL gen (ADR-0026 steps 3-4)
Wires the stratified WHERE-expression fragment into the three
filter commands and compiles the resulting Expr to SQL.
Grammar (data.rs): the `update` / `delete` `where` clause is
now the expression fragment (`Subgrammar(&expr::OR_EXPR)`) in
place of the single `col = val` slot; `show data` gains an
optional `where <expr>` and an optional `limit <n>` (a
non-negative integer, validated at parse time). The
expression's right-hand operands are a schema-aware
`DynamicSubgrammar` so the hint panel still narrows to the
left column's type (ADR-0026 §8) — but the inner grammar is
permissive: a type-mismatched literal still parses (§7).
AST: `RowFilter::Where{column,value}` -> `RowFilter::Where(Expr)`;
`ShowData` gains `filter: Option<Expr>` and `limit: Option<u64>`.
A `RowFilter::eq` convenience constructor keeps simple-equality
call sites and tests readable.
SQL (db.rs): `compile_expr` lowers an `Expr` to a
parameterised WHERE — every literal a `?` placeholder,
identifiers `quote_ident`-quoted, `<>` for inequality. A
literal compared against a column binds through that column's
type where compatible and falls back to its syntactic shape on
a mismatch (§7 — permissive). `show data ... limit n` emits
`LIMIT ?` with an implicit primary-key `ORDER BY`, so it is a
stable "first n by primary key".
completion.rs: `invalid_ident_at_cursor` no longer mis-flags a
digit-led literal (`1`) as an unknown column now that the
WHERE operand slot also accepts a column reference; a
`ProseOnly` slot suppresses keyword candidates even when the
expected set also carries a column ident.
11 db integration tests cover AND / OR / NOT, BETWEEN, IN,
LIKE, filtered `show data`, and limit ordering; walker and
expr unit tests cover the parse surface. Type-mismatch /
`= NULL` diagnostic flagging (§7 highlight + hint) is the
remaining ADR-0026 piece.
This commit is contained in:
+27
-2
@@ -139,8 +139,15 @@ pub enum Command {
|
||||
filter: RowFilter,
|
||||
},
|
||||
/// Render the rows of a table as a data view in the output.
|
||||
/// An optional `where` filters rows; an optional `limit`
|
||||
/// caps the row count (ADR-0026 §5). When `limit` is set the
|
||||
/// query is implicitly ordered by the table's primary key,
|
||||
/// so `limit n` is a stable "first n by primary key" rather
|
||||
/// than an arbitrary subset.
|
||||
ShowData {
|
||||
name: String,
|
||||
filter: Option<Expr>,
|
||||
limit: Option<u64>,
|
||||
},
|
||||
/// Replay a sequence of DSL commands from a file. Each line
|
||||
/// is parsed and dispatched through the same pipeline as
|
||||
@@ -235,10 +242,28 @@ pub enum ChangeColumnMode {
|
||||
/// `--all-rows` flag opt-in for unfiltered operations.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RowFilter {
|
||||
Where { column: String, value: Value },
|
||||
/// Operate on rows matching this WHERE expression
|
||||
/// (ADR-0026 — a full boolean expression, not just a single
|
||||
/// equality).
|
||||
Where(Expr),
|
||||
AllRows,
|
||||
}
|
||||
|
||||
impl RowFilter {
|
||||
/// Build a `Where` filter for a single `column = value`
|
||||
/// equality. The pre-ADR-0026 grammar produced exactly this
|
||||
/// shape; the constructor stays as a convenience for
|
||||
/// callers and tests that only need simple equality.
|
||||
#[must_use]
|
||||
pub fn eq(column: impl Into<String>, value: Value) -> Self {
|
||||
Self::Where(Expr::Predicate(Predicate::Compare {
|
||||
left: Operand::Column(column.into()),
|
||||
op: CompareOp::Eq,
|
||||
right: Operand::Literal(value),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// A complex WHERE expression (ADR-0026 §4).
|
||||
///
|
||||
/// Built by `grammar::expr::build_expr` from the flat
|
||||
@@ -414,7 +439,7 @@ impl Command {
|
||||
Self::CreateTable { name, .. }
|
||||
| Self::DropTable { name }
|
||||
| Self::ShowTable { name }
|
||||
| Self::ShowData { name } => name,
|
||||
| Self::ShowData { name, .. } => name,
|
||||
Self::AddColumn { table, .. }
|
||||
| Self::DropColumn { table, .. }
|
||||
| Self::RenameColumn { table, .. }
|
||||
|
||||
Reference in New Issue
Block a user