Skip to Content
We are live but in Staging 🎉

Catalog

information_schema

Both views are synthesized from the live schema on every query, so a column added a moment ago is already there. There is one schema, public.

information_schema.tables — table_catalog, table_schema, table_name, table_type (BASE TABLE).

information_schema.columns — table_schema, table_name, column_name, ordinal_position, data_type, is_nullable (YES/NO), column_default, character_maximum_length, datetime_precision.

SELECT column_name, data_type, character_maximum_length, datetime_precision, is_nullable FROM information_schema.columns WHERE table_name = 'orders' ORDER BY ordinal_position;
column_name | data_type | character_maximum_length | datetime_precision | is_nullable -------------+--------------------------+--------------------------+--------------------+------------- id | bigint | | | NO customer_id | bigint | | | NO note | text | 64 | | YES total | numeric | | | NO placed_at | timestamp with time zone | | 3 | NO payload | jsonb | | | YES

data_type uses Postgres names: bigint, integer (only for the 32-bit int storage type), smallint, real, double precision, numeric, text, boolean, timestamp with time zone, date, bytea, jsonb (for JSON and JSONB alike), uuid. A column declared INTEGER reports bigint because that is how it is stored (Data types → Integers). Arrays, structs and vectors report text.

Filtering on table_name and on a single column_name = '…' equality is honoured; the projection you ask for is the projection you get, so SELECT column_name FROM … returns one column, as psql’s \d expects.

Only these two views are served. information_schema.table_constraints, key_column_usage, referential_constraints and the rest are not intercepted and fail as an undefined table (42P01), so foreign keys, enforced as they are, are never reported back (Constraints).

pg_catalog

The adapter intercepts the catalog queries real drivers send and answers them from a fixed model. It is an emulation with a known edge, not a real catalog.

QueryStatusAnswer
SELECT version()SupportedPostgreSQL 16.0 (Dodil Tables adapterd) on x86_64, compiled by rustc, 64-bit
current_database(), current_schema(), current_user, session_userSupportedThe bucket name; public; the login user. Call these probes alone: SELECT version(), x returns only the version column.
current_setting('name'), set_config('name', 'v', false)SupportedRead and (no-op) write of session settings; used by Django’s connect sequence.
pg_is_in_recovery()Supportedfalse, when it is the only expression. clock_timestamp() does not exist (42P01); use now().
pg_typePartialThe 14 types the wire uses: bool, bytea, int8, int2, int4, text, json, float4, float8, date, timestamptz, numeric, uuid, jsonb, each with its array OID. psycopg’s and pgx’s type-resolution probes are answered from this list.
pg_namespacePartialOne row, public.
pg_databasePartialOne row, the connected bucket.
pg_class joined with pg_namespace (existence probes)PartialAnswers “does table x exist” for SQLAlchemy create_all, Prisma and Alembic. Column-level pg_attribute detail is not served; use information_schema.columns.
Prisma’s introspection battery (extensions, views, enums, sequences, functions, check constraints, foreign keys)PartialEach query is answered with its exact projected columns and zero rows, so prisma db push sees an empty database and emits CREATE TABLE.
SELECT 1, SELECT <int> liveness pingsSupportedAnswered locally.
Any other pg_catalog.* or pg_* table (pg_stat_activity, pg_indexes, pg_views, pg_constraint, pg_attrdef, pg_proc, …)Refused42P01Falls through to the planner and fails as an undefined table.

Because of that last row, an administrative tool that reads pg_stat_* or pg_locks will not work here, and an ORM feature that needs pg_indexes (index reflection) sees no indexes. Table and column reflection, which is what migrations and model discovery need, works.

Session settings

SHOW <name> answers a fixed list; every other name is refused.

SHOWValue
server_version16.0 (Dodil Tables adapterd)
client_encodingUTF8
standard_conforming_stringson
DateStyleISO, MDY
TimeZoneUTC
integer_datetimeson
search_path"$user", public

SET of these has no effect. SET statement_timeout and the vector knobs do work; SHOW statement_timeout reports the session value (5s, 250ms, 0) since 0.1.44. Anything not in the list above is refused the same way (Statements → Session).

DESCRIBE, SHOW, EXPLAIN

These are the engine’s native catalog statements, and they are the fastest way to see exactly what was stored.

DESCRIBE orders;
column | type | nullable | pk | default -------------+-----------------+----------+-------+---------------------------- id | long | false | true | customer_id | long | false | false | note | string(64) | true | false | status | string | false | false | 'open' total | decimal(18,2) | false | false | placed_at | timestamp(3) | false | false | CURRENT_TIMESTAMP ref | uuid | true | false | payload | json | true | false |

type is the storage type with its declared width or precision: string(n) for VARCHAR(n)/CHAR(n), decimal(p,s), timestamp(p), vector<n>, array<long>, struct<…>. since 0.1.43 for the width and precision suffixes.

StatementReturns
SHOW TABLESone row per table: table, pk_columns
SHOW DATABASES / SHOW SCHEMASthe databases visible to the connection
SHOW VECTOR INDEXEStable, column, kind (hnsw/ivfflat), state (building/ready), parameters
SHOW GRAPHSgraph name and its node and edge tables
DESCRIBE DATABASE dstorage location and table count
EXPLAIN <statement>one row, columns explain_key / explain_value: the physical plan the engine chose. Executes nothing.

A table created without a primary key has a hidden key column, _rowid. DESCRIBE shows it; information_schema and the pg_catalog emulation hide it so ORM model discovery does not pick up a phantom column.

psql

\dt lists the tables (as table_catalog, table_schema, table_name, table_type). \d <table> shows Column / Type / Nullable / Default and the primary-key index line; its Type column is the Postgres name without widths (text, numeric), so read widths from information_schema.columns or DESCRIBE. \di and \dv fail because pg_indexes and pg_views are not served; use SHOW VECTOR INDEXES and DESCRIBE.