introspect refuses smallint and its array form:
ai_messages.feedback: column type smallint has no equivalent in the DSL;
importing it as anything else would propose changing the real column
analytics_events.pos_x/pos_y/
viewport_w/viewport_h: smallint
task_recurrences.weekdays: smallint[]
The refusal is right — importing smallint as Int would make every diff propose ALTER COLUMN … TYPE integer forever. But smallint is not an exotic type. Text, Varchar, Int, BigInt, Float, Numeric, Bool, UUID, Timestamp, Date, Time, Bytes, Enum and Vector are all declarable; the 2-byte integer is the one gap in the integer family, and Numeric(p, s) was the last comparable one (#81).
Why it matters for adoption
Because the gate is all-or-nothing per registry (#109), a smallint column takes its whole table out — and in a whole-database survey of a 68-table schema this was the most widespread of the six blocker classes by column count: 6 columns across 3 tables, ahead of composite UNIQUE (5) and composite PRIMARY KEY (2).
The three tables are the ordinary reasons anyone reaches for smallint:
- a bounded rating (
ai_messages.feedback)
- screen geometry on a high-volume events table (
analytics_events, four columns)
- a set of weekday numbers (
task_recurrences.weekdays, smallint[])
What the workaround costs
Widen to integer. For the rating and the weekday set that is free and nobody would notice. For analytics_events it is 4 columns × 2 bytes × every row of an events table, forever, and — the part that matters more than the bytes — it is a schema change whose only justification is the declaration language. An adopter applying the rule "only make a schema change you would defend if sqlb vanished tomorrow" cannot take it. It is the same asymmetry #109 describes for the surrogate primary key, at lower cost and higher frequency.
smallint[] has no workaround at all short of rewriting the column as integer[], with the same objection.
Suggested shape
The narrowest version, mirroring what Numeric needed for #81:
schema.SmallInt("pos_x") // smallint, Go int16
schema.SmallInt("weekdays").Array() // smallint[], Go []int16
- a
TypeSmallInt beside TypeInt, rendering smallint
int16 on the Go side ([]int16 for the array), so a Describe over existing sqlc output — which already emits int16 for smallint — matches without a type override
- an entry in
IsArrayElement, which already admits every other scalar
- the
introspect mapping, closing the round trip
No new capability semantics: smallint filters, sorts and orders exactly as Int does.
Not in scope
smallserial, and the question of whether Int should accept a width argument rather than gaining a sibling. A separate constructor matches how BigInt is already spelled.
Found by sqlb-survey (#113) over a 68-table production schema — the one blocker class in that survey with no filed issue behind it.
introspectrefusessmallintand its array form:The refusal is right — importing
smallintasIntwould make every diff proposeALTER COLUMN … TYPE integerforever. Butsmallintis not an exotic type.Text,Varchar,Int,BigInt,Float,Numeric,Bool,UUID,Timestamp,Date,Time,Bytes,EnumandVectorare all declarable; the 2-byte integer is the one gap in the integer family, andNumeric(p, s)was the last comparable one (#81).Why it matters for adoption
Because the gate is all-or-nothing per registry (#109), a
smallintcolumn takes its whole table out — and in a whole-database survey of a 68-table schema this was the most widespread of the six blocker classes by column count: 6 columns across 3 tables, ahead of compositeUNIQUE(5) and compositePRIMARY KEY(2).The three tables are the ordinary reasons anyone reaches for
smallint:ai_messages.feedback)analytics_events, four columns)task_recurrences.weekdays,smallint[])What the workaround costs
Widen to
integer. For the rating and the weekday set that is free and nobody would notice. Foranalytics_eventsit is 4 columns × 2 bytes × every row of an events table, forever, and — the part that matters more than the bytes — it is a schema change whose only justification is the declaration language. An adopter applying the rule "only make a schema change you would defend if sqlb vanished tomorrow" cannot take it. It is the same asymmetry #109 describes for the surrogate primary key, at lower cost and higher frequency.smallint[]has no workaround at all short of rewriting the column asinteger[], with the same objection.Suggested shape
The narrowest version, mirroring what
Numericneeded for #81:TypeSmallIntbesideTypeInt, renderingsmallintint16on the Go side ([]int16for the array), so aDescribeover existing sqlc output — which already emitsint16forsmallint— matches without a type overrideIsArrayElement, which already admits every other scalarintrospectmapping, closing the round tripNo new capability semantics:
smallintfilters, sorts and orders exactly asIntdoes.Not in scope
smallserial, and the question of whetherIntshould accept a width argument rather than gaining a sibling. A separate constructor matches howBigIntis already spelled.Found by
sqlb-survey(#113) over a 68-table production schema — the one blocker class in that survey with no filed issue behind it.