Reference

Introspection support

Check supported database versions, catalog objects, and snapshot-mapping limits.

The optional qubu/introspection entrypoint reads one selected database namespace through a user-owned CatalogConnection. It returns normalized catalog data and can map that data to canonical Snapshot v1. The application owns the driver and connection lifecycle. Snapshot diffing, migration planning, and DDL emission are separate Qubu capabilities; see the ownership map.

Version and namespace baseline

Adapter Baseline Selected namespace Product policy
PostgreSQL 12+ one PostgreSQL schema PostgreSQL only
SQLite 3.37+ one database, normally main attached databases are not combined
MySQL 8.0.16+ one MySQL database MariaDB requires a separate adapter

Version and product failures are structured diagnostics. The adapters do not silently downgrade to a different product's catalog rules.

Catalog facts

Fact PostgreSQL SQLite MySQL
Tables and visible columns pg_class, pg_attribute sqlite_schema, table_xinfo TABLES, COLUMNS
Native storage format_type declared type COLUMN_TYPE
Defaults pg_get_expr dflt_value COLUMN_DEFAULT
Generated columns stored expressions stored/virtual when CREATE SQL is recoverable stored/virtual and GENERATION_EXPRESSION
Identity behavior attidentity INTEGER PRIMARY KEY, AUTOINCREMENT AUTO_INCREMENT
Keys and foreign keys pg_constraint table metadata and foreign_key_list TABLE_CONSTRAINTS, KEY_COLUMN_USAGE, REFERENTIAL_CONSTRAINTS
Checks pg_constraint and decompiled definition CREATE SQL CHECK_CONSTRAINTS
Indexes pg_index, access method, decompiled terms index_list, index_xinfo, schema SQL STATISTICS
Complete PostgreSQL objects views/materialized views, sequences, enums/domains, collations, triggers, routines, partitions, row-level policies, comments/owners, and extensions N/A N/A
Complete SQLite objects N/A views and triggers when CREATE SQL is recoverable; table/view columns from table_xinfo N/A
Complete MySQL objects N/A N/A typed views and view columns, routines and parameters, triggers, partitions, used collations, comments, and opaque scheduled events
Unsupported MySQL families N/A N/A sequences, materialized views, row-level security (RLS) policies, extensions, and ownership
Deferred or opaque objects foreign tables and relation kinds without a safe typed mapping virtual/shadow tables, attached-database boundaries, and unrecoverable definitions scheduled events are opaque; unknown or other non-base table rows are deferred

The readers preserve physical names and use database catalog identifiers only as current-run join keys. The normalized catalog keeps opaque SQL and its source, whether it came from a catalog value, a database decompiler, or CREATE SQL.

PostgreSQL complete catalog surface

The PostgreSQL reader also fills the complete normalized catalog used by Snapshot v1. It keeps PostgreSQL OIDs in current-run physical references and keeps decompiler output such as pg_get_viewdef, pg_get_triggerdef, and pg_get_functiondef as tagged SQL data. It does not evaluate that text.

The query and normalization layout follows the catalog-oriented parts of the Drizzle PostgreSQL introspector, while Qubu keeps the result as typed data instead of generating TypeScript declarations.

Use mapCatalogToSnapshot() or its explicit mapCatalogToCompleteSnapshot() alias for this object set. Both produce the canonical Snapshot v1 shape.

SQLite complete catalog surface

The SQLite reader uses fixed statements over sqlite_schema and the table-valued PRAGMAs database_list, table_list, table_xinfo, index_list, index_xinfo, and foreign_key_list. Each table-valued PRAGMA receives bound namespace or object parameters through the caller's CatalogConnection. The reader does not interpolate a database name into SQL.

SQLite views and triggers become typed catalog objects when Qubu can recover their definition and target from CREATE SQL. Their SQL remains opaque data, tagged with the sqlite dialect and a catalog reference.

Generated column expressions, declared storage types, SQLite affinity, rowid aliases, and AUTOINCREMENT are kept as column or identity dialect extensions. User indexes retain ordered column or expression terms and partial predicates.

Inline UNIQUE constraints are recovered from their internal indexes with deterministic Qubu names, so SQLite's sqlite_autoindex_* names do not become persisted logical IDs.

SQLite virtual tables and shadow tables remain typed deferred objects with an unmodeled-object diagnostic.

A selected attached database can expose table PRAGMA rows, but its schema SQL is outside the fixed main and temp statements. Qubu marks that result as limited and keeps other attached databases as opaque boundary records. It never combines attached databases into the selected namespace. SQLite does not provide the PostgreSQL object families such as routines, materialized views, policies, or ownership, so the reader does not fabricate them.

mapCatalogToSnapshot() delegates to mapCatalogToCompleteSnapshot() and retains typed views, triggers, deferred objects, opaque boundaries, and dialect extensions in Snapshot v1.

The query and normalization seams follow the catalog-reading portions of the Drizzle SQLite introspector. Drizzle's module generates source declarations; Qubu keeps the same SQLite metadata sources as normalized data and never evaluates database-provided SQL. The optional source generator consumes the strict Snapshot v1 result through a separate controlled printer.

MySQL 8 complete catalog surface

The MySQL reader accepts MySQL 8.0.16 and later within the MySQL 8 series. It rejects MariaDB and older MySQL versions instead of applying MySQL catalog rules to a different product or server version.

It reads INFORMATION_SCHEMA rows for one selected database and retains database-provided SQL as tagged, unevaluated MySQL data.

MySQL has typed records for:

  • Views.
  • Routines and their parameters.
  • Triggers and partitions.
  • Collations used by selected tables or columns.
  • Comments.

View definitions come from INFORMATION_SCHEMA.VIEWS; each view's columns are joined back to the matching COLUMNS rows by physical table name, so the complete Snapshot v1 cross-reference points at the view's own column IDs. Missing view definitions or unresolved trigger, partition, or other object references become deferred records with diagnostics.

Scheduled events are retained as CatalogOpaqueObject records. Their event metadata and definition remain opaque, and the reader emits an unmodeled-object warning. Snapshot v1 keeps these records in opaqueObjects; they are not treated as typed routines, triggers, or migration operations.

The MySQL reader does not expose typed sequences or materialized views. A sequence-like or other non-base table row is retained as a deferred object when the catalog reports one. MySQL row-level security (RLS) policies, extension objects, and ownership are unsupported complete families. Definers on views, routines, triggers, and events remain dialect metadata; they do not become ownership records. The corresponding capability flags are false.

The query and normalization layout follows the catalog-reading portions of the Drizzle MySQL introspector, while Qubu keeps the result as typed data instead of generating TypeScript declarations.

Use mapCatalogToSnapshot() or mapCatalogToCompleteSnapshot() to retain these typed MySQL families and the opaque or deferred boundaries in Snapshot v1.

Snapshot v1 surface

The mapper emits these facts in canonical Snapshot v1:

  • one namespace and ordinary tables;
  • exact dialect-native column storage;
  • nullability and unambiguous literal or opaque SQL defaults;
  • generated columns with stored or virtual mode;
  • identities kept separate from defaults and generated columns;
  • primary, unique, nullable-unique, foreign-key, and check constraints;
  • ordered column or expression index terms, predicates, included columns, and representable dialect extensions;
  • stable logical IDs with physical names preserved separately.

Strict mode returns no snapshot when a supported table fact cannot be mapped soundly. Lossy mode is explicit and marks warnings in the result. A fingerprint is canonical content, not an identity or rename marker.

Deferred and limited features

Supported object families become typed Snapshot v1 records, as described in the database sections above. Limits still apply to individual features:

  • PostgreSQL identity sequence options that have no typed field;
  • SQLite virtual/shadow tables, attached namespaces, and unrecoverable generated or expression definitions;
  • MySQL/MariaDB differences, prefix indexes, invisible indexes, and advanced functional, full-text, or spatial index semantics.

Use the Snapshot v1 mapper to retain supported PostgreSQL and MySQL families. MySQL scheduled events stay opaque, and MySQL sequences, materialized views, row-level security (RLS) policies, extension objects, and ownership stay unsupported or deferred. When a row cannot be normalized safely, the reader keeps a typed deferred or opaque record and emits a diagnostic instead of dropping it.

Upstream references

The dialect reader structure follows useful patterns from Drizzle Kit while keeping Qubu's output data-only:

Those modules generate TypeScript declarations as part of their workflows. Qubu keeps catalog normalization, Snapshot v1 mapping, and optional source generation as separate pure boundaries, so diffing and planning do not depend on source generation.

See Database introspection for the connection adapter example, identity rules, diagnostics, and the later diff/planning boundary. See the PostgreSQL, SQLite, and MySQL snapshot pages for the pure serialization adapters.