Reference / Authoring
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
connection | string | no | self (the default), a warehouse connection id from list_connections, or the uploaded-file source id (which also needs upload). |
tables | array | no | Filter terms. Each is matched case-insensitively against any part of the fully-qualified table name. |
upload | string | no | Which uploaded file to read, as an upload id from create_file_upload. Required when connection is the workspace's uploaded-file source, and refused on any other connection - a warehouse has no uploads. There is no default and the newest upload is not assumed: a later upload would otherwise silently change what this call answers and what a published dashboard reads, so omitting it is refused with the newest ready upload named for you to pass back. |
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".
| Field | Meaning |
|---|---|
role | dimension, flow or stock. self only; warehouse columns carry no role yet. |
row_estimate | Rendered as Table: <name> (~<n> rows). Warehouse only. |
size_band | small, big or extreme. |
recommended_mode | inline, 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:
| Condition | Text |
|---|---|
| The schema read failed | Could not read the schema for connection "<c>": <err> |
| Nothing readable, warehouse | No 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, self | No readable tables are available for connection "<c>". The refresh allowlist may be misconfigured. |
| A filter that matches nothing | No 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 filter | tables 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 array | tables 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 any
connection belonging to a workspace you are a current member of, plus the built-in
self and the shared sample. Using a warehouse connection requires a paid plan;
self does not.
Check it worked
Every column your statement will name should appear in the listing with the type
you expect: the ones you break down by, and the ones each number is worked out
from. 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.