Skip to content

Commit 8eaf78e

Browse files
authored
Add static adapter dispatch dependencies
Add source-grounded static adapter.dispatch dependency extraction for dxt.
1 parent 48a307a commit 8eaf78e

18 files changed

Lines changed: 417 additions & 2 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# M2 Static Adapter Dispatch Dependency Slice
2+
3+
This slice adds static dependency extraction for literal `adapter.dispatch(...)`
4+
calls. It records `depends_on.macros` only. It does not execute macros, evaluate
5+
the callable returned by dispatch, implement materializations, parse profiles,
6+
open adapter connections, or support project `dispatch:` config.
7+
8+
## Upstream References
9+
10+
dbt Core v1, branch `1.latest`, commit `566b75d`:
11+
12+
- `core/dbt/context/providers.py::BaseDatabaseWrapper._get_adapter_macro_prefixes`
13+
defines adapter prefix order as adapter type hierarchy plus `default`.
14+
- `core/dbt/context/providers.py::BaseDatabaseWrapper._get_search_packages`
15+
defines dispatch package search: no namespace uses flattened lookup, configured
16+
dispatch order wins, and dependency namespace searches root project then the
17+
dependency package.
18+
- `core/dbt/context/providers.py::BaseDatabaseWrapper.dispatch` rejects dotted
19+
macro names and deprecated `packages`, then searches
20+
`{adapter_prefix}__{macro_name}` candidates.
21+
- `core/dbt/context/providers.py::ParseProvider` and `RuntimeProvider` expose
22+
the adapter wrapper to Jinja contexts. dxt only uses the static dependency
23+
shape here.
24+
25+
dbt Core v2 / Fusion foundation, branch `main`, commit `0529e06`:
26+
27+
- `crates/dbt-jinja/minijinja/src/dispatch_object.rs::DispatchObject` and
28+
`Object for DispatchObject::call` model dispatch as a callable object.
29+
- `dispatch_object.rs::get_adapter_prefixes`,
30+
`DispatchObject::get_search_packages`, and
31+
`macro_namespace_template_resolver` provide the Fusion architecture reference
32+
for prefix and namespace lookup.
33+
34+
## dxt Ownership
35+
36+
- `src/project/resolve.zig` owns the static dispatch lookup helper.
37+
- `src/project/jinja.zig` recognizes literal `adapter.dispatch(...)` while
38+
scanning model SQL and macro SQL.
39+
- `src/project/manifest.zig` already serializes the affected
40+
`depends_on.macros` arrays.
41+
42+
## Supported Surface
43+
44+
- `adapter.dispatch("macro_name")`
45+
- `adapter.dispatch("macro_name", "macro_namespace")`
46+
- `adapter.dispatch("macro_name", macro_namespace="macro_namespace")`
47+
48+
The first implementation uses the current local default prefix list
49+
`duckdb`, then `default`, until profile-derived adapter identity exists.
50+
51+
Unsupported shapes fail or remain ignored according to the existing scanner
52+
boundary: dynamic names, dynamic namespaces, dotted macro names,
53+
`packages=...`, non-string namespaces, extra args, and malformed nested calls.
54+
55+
## Validation
56+
57+
- Native Zig tests cover prefix precedence, default fallback, package namespace
58+
root override before dependency package, dotted-name rejection, unsupported
59+
argument shapes, and scanner dependency recording for both model SQL and macro
60+
SQL.
61+
- Pytest fixture `adapter_dispatch_static` validates manifest
62+
`depends_on.macros` through the Zig binary.
63+
- Pytest fixture `adapter_dispatch_missing` validates a missing static dispatch
64+
target fails as an unresolved macro.
65+
66+
## Stop Conditions
67+
68+
- Do not execute dispatched macros in this slice.
69+
- Do not implement adapter profile parsing or dispatch config parsing.
70+
- Do not add bundled dbt internal macros.
71+
- Do not add DuckDB connections, materialization execution, `run_results.json`,
72+
catalog introspection, or Python product runtime behavior.

PLAN.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,15 @@ graph-present internal `dbt` macro lookup for `depends_on.macros`; macro
300300
execution, adapter dispatch, bundled dbt macros, and materialization lookup
301301
remain separate M2 work.
302302

303+
Current static adapter dispatch dependency source note:
304+
`.agent/research/m2-static-adapter-dispatch-deps.md` maps upstream dbt Core v1
305+
`BaseDatabaseWrapper.dispatch` and Fusion `DispatchObject` behavior to dxt's
306+
static `depends_on.macros` extraction for literal `adapter.dispatch(...)` calls.
307+
This slice records dispatch macro dependencies only, using a temporary
308+
`duckdb`, `default` prefix list until profile-derived adapter identity exists.
309+
It does not execute dispatched macros, implement project `dispatch:` config,
310+
parse profiles, or run adapters.
311+
303312
The next source-grounded M1/M2 slices after macro block variant support are:
304313

305314
1. Extend the render-only artifact boundary to adapter-free docs generation:
@@ -666,4 +675,4 @@ Exit criteria:
666675
- Selector wildcard behavior is currently pinned to observed dbt Core 1.10 behavior. dbt Fusion preview currently differs for resource-type-prefixed wildcard selectors such as `model.<package>.*` and filename-suffix path selectors such as `path:*orders.sql`; a future Fusion-compatibility slice must decide whether to support a selector dialect switch or a compatible superset.
667676
- Compatibility planning now uses a source-grounded reference map under `.agent/research/dbt-upstream-reference-map.md`; future feature slices should name upstream dbt v1/v2 source references, dxt Zig owners, affected artifact fields, validation gates, and stop conditions before implementation.
668677
- The committed dbt Core M1 oracle harness lives in `scripts/check_dbt_core_m1_oracle.py`. It is optional developer-side Python tooling that requires `dbt-core` and `dbt-duckdb`, invokes dbt Core through its Python runner, runs `dxt parse` through the Zig binary, and compares stable manifest slices for the supported synthetic M1 fixture ladder. It ignores dbt internal package docs/macros that are outside the current dxt artifact scope, records a known allowed gap for installed-package exposure refs that dbt Core resolves to a root same-name model while dxt currently resolves package-local, and leaves full source-map parity, full artifact schemas, and execution parity for later slices.
669-
- Before broadening M2 product implementation, close or explicitly re-scope the remaining M1 macro-compatibility behavior gaps. Macro `docs`/`meta` patch fields are covered for the current scalar artifact subset. Macro argument extraction under dbt Core v1 `flags.validate_macro_args` semantics and YAML patch argument validation/replacement are implemented for the manifest artifact surface. Static macro dependency lookup now uses the supported dbt order of current package, root project, other-package fallback for macro bodies, and graph-present internal `dbt` macros; adapter dispatch, macro execution, bundled dbt internal macros, and materialization runtime lookup remain planned. `{% data_test %}` has native source-grounded parser coverage, but the local dbt Core 1.10 oracle rejects that tag before writing artifacts, so dbt-oracle coverage currently pins `{% test %}` and `{% materialization %}` block parity.
678+
- Before broadening M2 product implementation, close or explicitly re-scope the remaining M1 macro-compatibility behavior gaps. Macro `docs`/`meta` patch fields are covered for the current scalar artifact subset. Macro argument extraction under dbt Core v1 `flags.validate_macro_args` semantics and YAML patch argument validation/replacement are implemented for the manifest artifact surface. Static macro dependency lookup now uses the supported dbt order of current package, root project, other-package fallback for macro bodies, graph-present internal `dbt` macros, and literal `adapter.dispatch(...)` dependency extraction with a temporary `duckdb`, `default` prefix list. Macro execution, bundled dbt internal macros, project `dispatch:` config, profile-derived adapter identity, and materialization runtime lookup remain planned. `{% data_test %}` has native source-grounded parser coverage, but the local dbt Core 1.10 oracle rejects that tag before writing artifacts, so dbt-oracle coverage currently pins `{% test %}` and `{% materialization %}` block parity.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Implemented pre-alpha commands:
4040
./zig-out/bin/dxt docs generate --project-dir tests/fixtures/docs_blocks --target-path target-dxt
4141
```
4242

43-
`parse`, `ls`, `compile`, `run`, `build`, and `docs generate` currently support only the documented M1/M2 parser and render-only subset: `dbt_project.yml` name/model paths/seed paths/macro paths/target path, `flags.validate_macro_args` for macro manifest argument validation, and top-level scalar `vars`, CLI `--vars` scalar overrides, SQL model discovery, CSV seed discovery, installed package SQL model and CSV seed discovery from `dbt_packages`, source discovery, installed package source discovery, exposure discovery, installed package exposure discovery, project macro discovery, installed package macro discovery from `dbt_packages`, project and package docs block discovery, literal and narrow scalar `var('name')` / `var('name', 'default')`-backed `ref` to models or seeds, two-argument package refs, package-local refs in installed package models and exposures, dbt-style fallback from unqualified refs to a unique installed-package model or seed, literal and narrow scalar `var('name')` / `var('name', 'default')`-backed `source`, package-local sources in installed package models, dbt-style fallback from unqualified sources to a unique installed-package source, literal `doc` in descriptions, package-qualified, package-local, root-fallback, macro-body other-package fallback, and graph-present internal `dbt` macro dependencies, basic inline `config`, narrow project and package YAML model properties and macro properties including patched macro `docs`, scalar `meta`, YAML `arguments`, and dbt Core v1-style macro argument annotation warnings, project and package model/seed `+docs.node_color`, root-project model config overrides for installed packages, simple columns, tags, materialization and disabled SQL models, dbt-shaped generic test nodes for `unique`, `not_null`, `accepted_values`, and `relationships`, model/test `refs` and `sources` artifact fields, deterministic partial `manifest.json`, and basic name/tag/path/package/resource/config materialization selectors with exact `package:`/`package:this`, comma intersections, whitespace unions, multi-argument selector lists, repeated selector flags, and graph expansion. This is not full dbt `var()` compatibility yet: `vars.yml`, nested/package-scoped vars, non-string values, `var.has_var`, Jinja-rendered var values, profile/project rendering with vars, and general `var()` usage remain planned. `compile` applies selectors/excludes to enabled SQL models, writes supported compiled SQL to `target/compiled/<package>/...`, and emits compile fields for compiled models. `run` and `build` are truthful execution preflight commands: they parse, resolve, apply selectors/excludes, compile supported selected models, write `manifest.json`, and then fail before execution with a clear adapter-runner boundary error. They do not run SQL, materialize relations, run tests, or write `run_results.json`. `docs generate` uses the same render-only compiler, writes `manifest.json`, writes compiled SQL for selected enabled SQL models, and emits an adapter-free empty `catalog.json` until relation introspection exists. The compiler currently renders only `config`, literal and narrow scalar var-backed `ref`, and literal and narrow scalar var-backed `source` calls; macro execution, adapter dispatch, materializations, tests, real `run`/`build` execution, non-empty catalog introspection, and `docs serve` remain planned.
43+
`parse`, `ls`, `compile`, `run`, `build`, and `docs generate` currently support only the documented M1/M2 parser and render-only subset: `dbt_project.yml` name/model paths/seed paths/macro paths/target path, `flags.validate_macro_args` for macro manifest argument validation, and top-level scalar `vars`, CLI `--vars` scalar overrides, SQL model discovery, CSV seed discovery, installed package SQL model and CSV seed discovery from `dbt_packages`, source discovery, installed package source discovery, exposure discovery, installed package exposure discovery, project macro discovery, installed package macro discovery from `dbt_packages`, project and package docs block discovery, literal and narrow scalar `var('name')` / `var('name', 'default')`-backed `ref` to models or seeds, two-argument package refs, package-local refs in installed package models and exposures, dbt-style fallback from unqualified refs to a unique installed-package model or seed, literal and narrow scalar `var('name')` / `var('name', 'default')`-backed `source`, package-local sources in installed package models, dbt-style fallback from unqualified sources to a unique installed-package source, literal `doc` in descriptions, package-qualified, package-local, root-fallback, macro-body other-package fallback, graph-present internal `dbt` macro dependencies, and literal `adapter.dispatch(...)` macro dependencies using a temporary `duckdb`, `default` prefix list, basic inline `config`, narrow project and package YAML model properties and macro properties including patched macro `docs`, scalar `meta`, YAML `arguments`, and dbt Core v1-style macro argument annotation warnings, project and package model/seed `+docs.node_color`, root-project model config overrides for installed packages, simple columns, tags, materialization and disabled SQL models, dbt-shaped generic test nodes for `unique`, `not_null`, `accepted_values`, and `relationships`, model/test `refs` and `sources` artifact fields, deterministic partial `manifest.json`, and basic name/tag/path/package/resource/config materialization selectors with exact `package:`/`package:this`, comma intersections, whitespace unions, multi-argument selector lists, repeated selector flags, and graph expansion. This is not full dbt `var()` compatibility yet: `vars.yml`, nested/package-scoped vars, non-string values, `var.has_var`, Jinja-rendered var values, profile/project rendering with vars, and general `var()` usage remain planned. `compile` applies selectors/excludes to enabled SQL models, writes supported compiled SQL to `target/compiled/<package>/...`, and emits compile fields for compiled models. `run` and `build` are truthful execution preflight commands: they parse, resolve, apply selectors/excludes, compile supported selected models, write `manifest.json`, and then fail before execution with a clear adapter-runner boundary error. They do not run SQL, materialize relations, run tests, or write `run_results.json`. `docs generate` uses the same render-only compiler, writes `manifest.json`, writes compiled SQL for selected enabled SQL models, and emits an adapter-free empty `catalog.json` until relation introspection exists. The compiler currently renders only `config`, literal and narrow scalar var-backed `ref`, and literal and narrow scalar var-backed `source` calls; macro execution, project `dispatch:` config, profile-derived adapter identity, materializations, tests, real `run`/`build` execution, non-empty catalog introspection, and `docs serve` remain planned.
4444

4545
## Development
4646

0 commit comments

Comments
 (0)