Files
rdbms-playground/docs/simple-mode-limitations.md
T
claude@clouddev1 942222bfc9 constraints: CHECK — check (<expr>) at create table & add column (ADR-0029)
The fourth constraint. `check ( <expr> )` reuses the ADR-0026
WHERE-expression grammar via `Subgrammar`, so a check is
written in the same language as a `where` filter.

- Grammar: a `CHECK_CONSTRAINT` arm joins the shared
  constraint-suffix Choice; `consume_check_expr` extracts the
  parenthesised expression (paren-depth aware) into
  `ColumnSpec.check` / `Command::AddColumn.check`.
- Storage: the parsed `Expr` is compiled once to inline SQL
  (`compile_check_sql` — `compile_expr` + ADR-0028's
  param-inliner) and stored in that form everywhere — a new
  `check_expr` column in `__rdbms_playground_columns`,
  `project.yaml`'s `ColumnSchema.check`, and the column DDL
  emitted by `do_create_table` / `schema_to_ddl`.
- `add column … check` routes through the rebuild primitive
  (SQLite's `ALTER … ADD COLUMN` cannot carry it); a CHECK on
  a serial/shortid column is create-table-only and refused at
  add-column with a friendly message.
- `describe` surfaces the CHECK. ADR-0029 §7/§8 updated to the
  SQL-form decision — double-quoted identifiers, consistent
  with ADR-0028's `explain` display SQL.

1201 tests pass (+8); clippy clean.
2026-05-19 16:42:18 +00:00

56 lines
2.2 KiB
Markdown

# Simple-mode query limitations
Simple mode's DSL query surface is deliberately a *subset*
of SQL. The DSL is a teaching on-ramp; advanced mode (raw
SQL) is the full surface. This document is the running
list of what a simple-mode query cannot express that
advanced-mode SQL can.
It serves two audiences:
- **Students** — each entry is the seed of a short
explanation of why the boundary exists and what to use
instead (often: switch to advanced mode).
- **Designers** — the consolidated list feeds the future
`Q4` SQL-subset specification: the inverse view of what
the supported subset deliberately leaves out.
The list grows as new simple-mode surface lands; each
entry names the ADR that drew the boundary.
## WHERE expressions (ADR-0026)
- **Comparison operands are a column or a literal**, not a
nested expression. `(a > b) = (c > d)` — comparing two
boolean sub-expressions — cannot be written. Parentheses
group boolean sub-expressions, not comparison operands.
- **A bare column is not a boolean.** A predicate always
has an operator: write `Active = true`, not `Active`.
- **No arithmetic** in expressions (`Price * 1.1`).
- **No string concatenation.**
- **No scalar functions** (`upper(Name)`, `length(x)`, …).
- **No subqueries**, and no `EXISTS`.
## Query shape (ADR-0026)
- **No `ORDER BY`.** `show data … limit <n>` orders
implicitly by the primary key; explicit ordering is not
yet available.
- **No `LIMIT … OFFSET`** — `limit` takes a row count
only.
## Table creation (ADR-0029)
- **`create table` declares only primary-key columns.**
`create table T with pk …` makes every listed column part
of the primary key; there is no simple-mode syntax for a
non-PK column in the same statement. Non-PK columns are
added afterward with `add column`. Creating a table with a
mix of PK and non-PK columns in one statement needs
advanced-mode `CREATE TABLE` syntax.
- **`check (<expr>)` constraints reuse the WHERE-expression
grammar** (ADR-0026), so the same limits apply: no scalar
functions (`length(x)`), no arithmetic. A check is a boolean
combination of column-vs-literal comparisons, `LIKE`, `IN`,
`BETWEEN`, and `IS NULL`.