Skip to content

introspect_schema

List the tables and columns a cube SQL may read from a connection, with row estimates and semantic roles. Parameters, errors and scope.

Lists the tables and columns a cube SQL may read from a connection, and only those. It never exposes the full database. This is step one of authoring a refreshable dashboard: read the columns, pick low-cardinality dimensions and additive measures, then write and validate the SQL with validate_cube_sql.

Behaviour hints for clients: read-only, not open-world.

Parameters

ParameterTypeRequiredNotes
connectionstringnoself (the default) or a warehouse connection id from list_connections.
tablesarraynoFilter terms. Each is matched case-insensitively against any part of the fully-qualified table name.

Narrow with tables once you know what you are building

On a real warehouse an unfiltered introspect returns every readable table with every column, which is the single largest result in the authoring flow and mostly not about your dashboard. Because a term matches any part of the qualified name, one argument serves as a database, schema or table filter: on Snowflake SALES narrows to that database and SALES.PUBLIC to that schema; on Postgres and self the names are bare, so pass the table name. Omit it the first time, when you genuinely want to see what is there.

Returns

Readable schema for connection "self".
Table: dashies_usage_metrics
- day: date - dimension: the UTC day the metric was recorded
- publishes: bigint - flow: dashboards published that day
- active_dashboards: bigint - stock: dashboards live at the end of that day

BEGIN_JSON
{"connection":"self","tables":[{"name":"dashies_usage_metrics","columns":[{"name":"day","type":"date","role":"dimension","description":"..."}]}]}
END_JSON

With a filter applied the header instead reads Readable schema for connection "<c>" - 3 of 214 tables matching "orders".

FieldMeaning
roledimension, flow or stock. self only; warehouse columns carry no role yet.
row_estimateRendered as Table: <name> (~<n> rows). Warehouse only.
size_bandsmall, big or extreme.
recommended_modeinline, parquet or reject.

Never SUM a stock column

flow accumulates across the grain and is safe to sum. stock is a level measured at one instant, and summing it across a time grain recounts the same entities every period. A cohort cube summing ending ARR over 24 tenure months once reported 596 million dollars against a real 36 million. Only self columns carry the role, so on a warehouse you have to know this yourself, and declare it with stock_columns when you validate.

The row estimate is the remote planner's approximation, captured when the connection was created or last resynced. Treat it as a scale signal, never an exact count. A table with no estimate may simply be unanalyzed on the remote; the fast exact check is validate_cube_sql with select count(*) as n from <table>, which pushes down to the remote and stays fast at millions of rows.

It returns column names, not column values

Before writing a filter predicate or a conditional count against an enum-like column, confirm its real values with a quick validate_cube_sql that groups by that column. Introspection cannot tell you what is in a column.

Errors

The shared connection rules, plus:

ConditionText
The schema read failedCould not read the schema for connection "<c>": <err>
Nothing readable, warehouseNo readable tables are available for connection "<c>". The connection has no readable tables yet - check the imported schema(s) and that the read-only role can SELECT them.
Nothing readable, selfNo readable tables are available for connection "<c>". The refresh allowlist may be misconfigured.
A filter that matches nothingNo readable table on connection "<c>" matches "<f>". Each filter is matched case-insensitively against the fully-qualified table name, so any part of one works. Available: <up to 40 names> (+<n> more).
A malformed filtertables must be an array of table-name filters (or a single string) - each is matched case-insensitively against the fully-qualified table name.
An empty filter arraytables must contain at least one filter - omit it entirely to list every readable table.

A filter that matches nothing lists what is actually there, so the fix is one corrected call rather than an unfiltered re-list of the whole warehouse.

Scope

Connection-scoped, so there is no workspace argument. It accepts a connection you own personally or one belonging to a workspace you are a current member of. Using a warehouse connection requires a paid plan; self does not.

Check it worked

Every column you intend to group by or aggregate should appear in the listing with the type you expect. If a table you know exists is missing, check the connection's imported schemas in the web app rather than assuming the filter is wrong, and re-run without tables to see the full set.

Last updated 2026-08-04