Skip to content

smallint has no declaration, so an ordinary integer width takes its whole table out of the gate — and widening the column to suit the DSL is a schema change the adopter cannot justify #114

Description

@jryannel

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions