e44d2983ab
Dropping a PK column was already refused in both modes via the shared do_drop_column guard; this adds end-to-end coverage on the advanced ALTER surface (single-column + compound PK, asserting refusal for the right reason) and documents the asymmetry that advanced-mode SQL can create a PK-less table (SQLite's implicit rowid keys it) while simple mode forbids it. See issue #19 comment for the full assessment.
3.2 KiB
3.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
Q4SQL-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, notActive. - 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—limittakes a row count only.
Table creation (ADR-0029)
- A simple-mode table always has a primary key; an advanced-mode
table need not.
create table … with pk …is mandatory in simple mode (ADR-0029) — the barewith pkeven defaults toid serial. Advanced-mode SQL follows standard SQL and permits a PK-less table:create table t (a int)declares no primary key. This is not a storage problem — every ordinary table (STRICT included) carries SQLite's implicitrowid, which keys it internally; only aWITHOUT ROWIDtable (which this app never creates) would lack one. So the simple-mode requirement is a pedagogical boundary (teach that tables should have a key), not an engine constraint. Consequences in a PK-less table, all handled:show data … limitfalls back to rowid order (no stable user-facing key to order by);update/deletestill target the affected rows by rowid; and there is no "PK column" to drop — dropping a declared PK column is refused in both modes (the shareddo_drop_columnguard: "cannot drop primary-key column …"). create tabledeclares 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 withadd column. Creating a table with a mix of PK and non-PK columns in one statement needs advanced-modeCREATE TABLEsyntax.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, andIS NULL.