Skip to content

driver-sql: introspectSchema() returns only { tables } — the spec IntrospectedSchema contract's dialect and (required) introspectedAt are never emitted #10998

Description

@os-warren

Found while fixing the introspection seam for #10676. Same seam, different key — filed separately so it does not ride that PR.

What

packages/spec/src/contracts/schema-diff-service.ts declares:

exportinterfaceIntrospectedSchema{tables: Record<string,IntrospectedTable>;dialect?: ...;introspectedAt: string;// required}

SqlDriver.introspectSchema() returns { tables } and nothing else. plugin.ts hands that value straight to ExternalDatasourceService, which is typed against the spec contract — so the service reads two keys the producer never sets.

Measured

Object.keys() of a real SqlDriver.introspectSchema() result, live in-memory SQLite at 368e7a06f:

["tables"]

dialect and introspectedAt are both undefined.

Consequences

Two, both silent:

  1. Type mapping runs with no dialect.ExternalDatasourceService.generateObjectDraft and refreshCatalog both call suggestFieldTypeForSqlType(col.type, schema.dialect as SqlDialect). With dialect undefined every remote column is mapped by the dialect-agnostic fallback, so any dialect-specific mapping the function implements is unreachable on the federation path — exactly the path that needs it.
  2. The persisted catalog records no dialect.refreshCatalog writes dialect: schema.dialect into the external_catalog metadata record that Studio's schema browser and the boot gate read back.

introspectedAt being absent while the contract declares it required is the sharper half: consumers are entitled to read it without a guard.

Relationship to #10676

Same root shape as the isPrimary / primaryKey collision that card is about: SqlDriver implements the IntrospectedSchema in packages/objectql/src/util.ts (which declares neither key), while everything downstream of plugin.ts is typed against the packages/spec one. #10676's fix repairs the primary-key column of that table; this is another column of it.

Whether the repair belongs in the driver (emit the spec shape) or in the spec (reconcile the two IntrospectedSchema declarations) is the same routing question #10676 raises for the column spelling, and the two should probably be decided together.

Not measured here

Only the SQLite arm was executed. introspectSchema builds its return value in one place for every dialect, so the omission is dialect-independent by construction — but Postgres/MySQL were read, not run.

Filed unassigned as a finding awaiting first-touch grading. Discovered from #10676.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions