feat: dbt_map_relations maps the tables of raw SQL to ref() and source() calls
What
dbt_map_relations { sql, dialect?, manifest_path? } is a read-only tool. It reads the tables of a raw SQL query and matches each one to the relation_name of a model, snapshot, seed or source in the dbt manifest. For each table it returns { raw, replaceWith, match, candidates }, where match is exact, case_insensitive, partial or none and replaceWith is a {{ ref('x') }} or {{ source('s', 't') }} call (the table as written when nothing matched). A model is preferred over a source when both match. It backs the plugin's /to-model command.
Tables come from altimate-core extractMetadata, which keeps only the last name part. The schema and database the person wrote are read back from the SQL text, so a fully written name picks the right relation. Quoted, upper-case, two- and three-part names are covered for Snowflake, BigQuery and Databricks.
Tests
bun test test/altimate/dbt-map-relations.test.ts: 27 pass. The first block prints what extractMetadata returns for each dialect and the matching rules are based on that. Every match value is covered, plus a missing manifest, unparseable SQL and SQL with no tables. bunx tsgo --noEmit is clean for the new file.
Cost side effects
None. No LLM calls, no warehouse calls, no adapter start. It reads manifest.json only.
Changelog lines
dbt_map_relationstool: map the tables of raw SQL toref()andsource()calls from the dbt manifest.
The plugin PR (/to-model) depends on this one. Merge this first.
Demo
Screen recording of a real run (branch CLI build, /to-model in a Claude Code session on a dbt fixture): /Users/harish/.quikim/artifacts/pu-mods/videos/P-13.mp4 (cast: P-13.cast). It shows dbt_map_relations output, the pane with unmatched and partial rows on top, the submitted instruction, and Claude asking before adding a source for the unmatched table.
🤖 Generated with Claude Code
Summary by cubic
Ships the first dbt Power User tool: dbt_map_relations maps each table a raw SQL query reads to the ref() or source() call that builds it, using the dbt manifest. The other eight tools are registered stubs that answer "not implemented".
Details
- A tokenizer reads the SQL per dialect: quoted names, strings, and dollar quotes are skipped, and whitespace or comments around dots and tables after a subquery in a
FROMlist are handled; a CTE's name is not a table, and a physical table a CTE shares its name with keeps its qualifiers. - Each table returns its best match and all candidates, ranked exact, case_insensitive, partial, then none, preferring a model over a source when both match; versioned models are referenced with
v=. - Quoted, upper-case, and two- and three-part names are covered for Snowflake, BigQuery, and Databricks.
dbtAdapterForgates every adapter-backed tool: it refuses read-only and plan-mode calls, sessions in another dbt project, and adapters that fail to start or load.AltimateApi.apiRequestcalls the backend with the stored credentials and names the credentials file in errors.- The tool is read-only: no LLM, warehouse, or adapter calls; it reads
manifest.jsononly, and fails clearly when run outside a dbt project withoutmanifest_path.
Summary by CodeRabbit
- New Features
- Added a tool that maps SQL table references to matching dbt models, snapshots, seeds, or sources, with candidate matches and suggested replacements.
- Added dbt and documentation-sharing tools to the available tool list. Several are placeholders and report that they are not implemented in this build.
- Tests
- Added coverage for relation mapping, tool availability, access checks, and API request handling.