build-a-sql-database / lesson-05.md
Lesson 05 · In-memory tables

Typed insert validation

A table should reject a row that does not fit its schema. Today you make insertion check the number of values and their types before accepting a row.

The goal

Reject a row whose length or column types do not match the table's schema, and accept one that does.

Start here - the target
TO DO
Scenario: Validating a row against the schema on insert
Givena table with schema (id INTEGER), (name TEXT)
Whenthe row [1, "alice"] is inserted
Thenit is accepted
Andinserting [1] is rejected (wrong number of values)
Andinserting ["x", "alice"] is rejected (id is not an integer)
Anda null value is accepted in any column
Background

A schema is a promise about the shape of every row, and the moment to enforce that promise is on the way in. Insert validation checks two things: that the row has exactly one value per column, and that each value’s type matches its column - an INTEGER column will not accept a text value.

The one exception is NULL, which is allowed to stand in for a value of any type; that is what makes it the universal “no data here” marker. Reject the two bad rows with a clear error and the good one silently, and every table in the database is now self-defending - no query downstream has to wonder whether a row is well-formed.

Make it work
func (t *Table) Insert(r Row) error {
// 1. len(r.Values) must equal len(schema.Columns)
// 2. each value's Kind must match the column Type, unless it is null
// return an error describing the first mismatch, else Append
}
CheckpointDONE
The table now guards its own integrity, refusing rows that break the schema. Commit and stop here.