Skip to content

isIndexed is available on an arbitrary subset of field types #860

Description

@borisno2

Found while fixing #859 (isIndexed: true emitting an invalid inline @index). Not a bug — filing so it doesn't evaporate.

The gap

isIndexed is declared on an arbitrary subset of field types:

Accepts isIndexed Does not
text, decimal, calendarDay, relationship integer, timestamp, select, checkbox, json, password

The split looks like historical accretion rather than a design decision. decimal and calendarDay have it while integer and timestamp don't, which is hard to justify on any axis — indexing a timestamp you filter or sort by is considerably more common than indexing a decimal.

Today timestamp({ isIndexed: true }) is a compile error. That's an honest failure and nowhere near as bad as what #859 fixed, so this isn't urgent — but it is a papercut for anyone coming from Keystone, where the option is uniform across field types.

Why this wasn't folded into #859

That PR is a bug fix (patch). Adding isIndexed to more field types is additive (minor), and it carries design questions of its own that deserve deciding rather than assuming.

Open questions

  1. Which types? integer and timestamp seem clearly worth having. select is less obvious — it maps to a Prisma enum on Postgres and a String on SQLite, so it's worth confirming the index is well-defined on both before offering it.
  2. json? Indexability is provider-specific (Postgres wants GIN and an expression, which @@index([field]) doesn't express). Probably out.
  3. password? Indexing a bcrypt hash has no sensible use case. Probably out.
  4. Should timestamp default to indexed? relationship defaults FKs to isIndexed: true for Keystone parity. Timestamps are a common sort key, but silently adding indexes to every existing table would be a surprising and non-trivial migration for existing users, so I'd lean no.
  5. virtual must be excluded regardless — it has no column, so isIndexed there could only ever no-op. This is the main argument against simply hoisting isIndexed onto BaseFieldConfig to make it uniform: it would document an option that lies for at least one field type.

Implementation note

The mechanism already exists as of #859. getPrismaType() returns an optional index?: boolean | 'unique' and the generator emits @@index([field]) / @@unique([field]) from it. Extending a field type is therefore: add isIndexed?: boolean | 'unique' to its config type, and return index from its getPrismaType(). No generator changes needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions