Query BLS Dataframes
bls_dataframe_queryRun a single-statement SELECT against the canvas dataframes registered by bls_get_series. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer — use bls_dataframe_describe to list available dataframes. Supports JOINs, aggregates, window functions, and CTEs. Optional register_as persists the result as a new dataframe with a fresh TTL for chained analysis. Canvas SQL operations consume zero BLS API quota. Requires CANVAS_PROVIDER_TYPE=duckdb.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | Single-statement SELECT against df_<id> tables on the shared canvas. Reference dataframes by the names returned in bls_get_series responses or listed by bls_dataframe_describe. Standard DuckDB SQL — joins, aggregates, window functions, CTEs all supported. Example: SELECT series_id, year, period, value FROM df_AAAAA_BBBBB WHERE year >= '2020' ORDER BY year DESC. | |
| preview | No | Inline row preview count. Defaults to row_limit. Set lower (e.g. 50) when chaining via register_as and only a sample is needed immediately. | |
| row_limit | No | Hard cap on rows materialized in the response (default 1000, max 10000). Full results live on-canvas under register_as when provided. | |
| register_as | No | When set, persist the query result as a new dataframe under this name. Fresh TTL — not inherited from parent tables. Use to chain analyses without re-running source SQL or consuming additional BLS quota. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cap | No | The preview or row_limit cap that was applied. | |
| rows | No | Materialized rows, bounded by preview / row_limit. | |
| error | No | Present when the call failed. Absent on success. | |
| shown | No | Number of rows returned inline. | |
| notice | No | Guidance when results were capped by preview or row_limit — names which parameter was the binding limiter and suggests how to retrieve the rest. Absent when all rows fit in the response. | |
| columns | No | Column names in projection order. | |
| row_count | No | Rows materialized by the query. Exact when register_as is used; otherwise equals row_limit when truncated is true. | |
| truncated | No | True when the returned rows were capped. | |
| expires_at | No | ISO 8601 expiry for the newly registered dataframe, when applicable. | |
| registered_as | No | Set when register_as was supplied and the result was materialized. |