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

2.2 KiB

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 … OFFSETlimit 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.