feat: dbt_map_relations maps the tables of raw SQL to ref() and source() calls

HK
1d ago
+1622-0

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_relations tool: map the tables of raw SQL to ref() and source() 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 FROM list 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.
  • dbtAdapterFor gates 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.apiRequest calls 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.json only, and fails clearly when run outside a dbt project without manifest_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.