dlin-cli 0.2.4rc3__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/Cargo.lock +9 -7
  2. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/Cargo.toml +2 -2
  3. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/PKG-INFO +20 -11
  4. {dlin_cli-0.2.4rc3/crates/dlin → dlin_cli-0.2.5}/README.md +19 -10
  5. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin/Cargo.toml +1 -0
  6. {dlin_cli-0.2.4rc3/crates/dlin-core → dlin_cli-0.2.5/crates/dlin}/README.md +19 -10
  7. dlin_cli-0.2.5/crates/dlin/src/cli/column.rs +240 -0
  8. dlin_cli-0.2.5/crates/dlin/src/cli/command.rs +247 -0
  9. dlin_cli-0.2.5/crates/dlin/src/cli/common.rs +126 -0
  10. dlin_cli-0.2.5/crates/dlin/src/cli/graph.rs +309 -0
  11. dlin_cli-0.2.5/crates/dlin/src/cli/misc.rs +163 -0
  12. dlin_cli-0.2.5/crates/dlin/src/cli/mod.rs +13 -0
  13. dlin_cli-0.2.5/crates/dlin/src/cli/summary.rs +321 -0
  14. dlin_cli-0.2.5/crates/dlin/src/commands/column.rs +315 -0
  15. dlin_cli-0.2.5/crates/dlin/src/commands/debug.rs +143 -0
  16. dlin_cli-0.2.5/crates/dlin/src/commands/graph.rs +529 -0
  17. dlin_cli-0.2.5/crates/dlin/src/commands/manifest.rs +383 -0
  18. dlin_cli-0.2.5/crates/dlin/src/commands/mod.rs +13 -0
  19. dlin_cli-0.2.5/crates/dlin/src/commands/shared.rs +331 -0
  20. dlin_cli-0.2.5/crates/dlin/src/main.rs +129 -0
  21. dlin_cli-0.2.5/crates/dlin/src/mcp/mod.rs +7 -0
  22. dlin_cli-0.2.5/crates/dlin/src/mcp/protocol.rs +227 -0
  23. dlin_cli-0.2.5/crates/dlin/src/mcp/tests.rs +824 -0
  24. dlin_cli-0.2.5/crates/dlin/src/mcp/tools.rs +529 -0
  25. dlin_cli-0.2.5/crates/dlin/tests/integration/artifacts.rs +47 -0
  26. dlin_cli-0.2.5/crates/dlin/tests/integration/cli.rs +682 -0
  27. dlin_cli-0.2.5/crates/dlin/tests/integration/error_format.rs +93 -0
  28. dlin_cli-0.2.5/crates/dlin/tests/integration/freshness.rs +359 -0
  29. dlin_cli-0.2.5/crates/dlin/tests/integration/generic_test_metadata.rs +654 -0
  30. dlin_cli-0.2.5/crates/dlin/tests/integration/manifest_only.rs +686 -0
  31. dlin_cli-0.2.5/crates/dlin/tests/integration/manifest_only_rest.rs +590 -0
  32. dlin_cli-0.2.5/crates/dlin/tests/integration/parsing.rs +65 -0
  33. dlin_cli-0.2.5/crates/dlin/tests/integration/sql_mode_test_warning.rs +154 -0
  34. dlin_cli-0.2.5/crates/dlin/tests/integration_test.rs +80 -0
  35. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/Cargo.toml +1 -0
  36. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5/crates/dlin-core}/README.md +19 -10
  37. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/error.rs +15 -0
  38. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/builder/mod.rs +49 -440
  39. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/project_yaml.rs +194 -0
  40. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/semantic_layer.rs +200 -0
  41. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/tests/build_graph/basic.rs +552 -0
  42. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/tests/build_graph/mod.rs +6 -0
  43. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/tests/build_graph/semantic_layer.rs +228 -0
  44. dlin_cli-0.2.5/crates/dlin-core/src/graph/builder/tests/build_graph/yaml_snapshots.rs +428 -0
  45. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/builder/tests/versioned.rs +4 -4
  46. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/mod.rs +0 -8
  47. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/sqllineage.rs +20 -16
  48. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/cache.rs +171 -0
  49. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/cross_model.rs +88 -55
  50. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/impact.rs +24 -42
  51. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/mod.rs +137 -47
  52. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/schema.rs +154 -53
  53. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/backend_regression/basic.rs +226 -0
  54. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/backend_regression/discovery.rs +424 -0
  55. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/backend_regression/mod.rs +324 -0
  56. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/backend_regression/set_operations.rs +575 -0
  57. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/cache.rs +618 -0
  58. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/core_cross_model/mod.rs +580 -0
  59. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/core_cross_model/scenarios.rs +701 -0
  60. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/core_star.rs +2 -0
  61. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/core_util.rs +21 -26
  62. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/tests/impact.rs → dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/impact/core.rs +22 -241
  63. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/impact/edge_cases.rs +117 -0
  64. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/tests/impact/mod.rs +188 -0
  65. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/regression_fixtures.rs +18 -3
  66. dlin_cli-0.2.5/crates/dlin-core/src/graph/column_lineage/types.rs +390 -0
  67. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/mod.rs +62 -33
  68. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/filter_graph.rs +120 -0
  69. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/selector.rs +44 -0
  70. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/types.rs +6 -3
  71. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/input.rs +86 -10
  72. dlin_cli-0.2.5/crates/dlin-core/src/parser/cache.rs +790 -0
  73. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/parser/discovery.rs +97 -15
  74. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/mod.rs +141 -0
  75. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/reachability/analysis.rs +67 -0
  76. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/reachability/catalog.rs +131 -0
  77. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/reachability/mod.rs +318 -0
  78. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/reachability/tests.rs +210 -0
  79. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/render.rs +704 -0
  80. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/source.rs +305 -0
  81. dlin_cli-0.2.5/crates/dlin-core/src/parser/jinja/tests.rs +1036 -0
  82. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/graph.rs +480 -0
  83. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/mod.rs +454 -0
  84. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/report/decode.rs +493 -0
  85. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/report/mod.rs +571 -0
  86. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/report/tests.rs +562 -0
  87. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/compatibility.rs +366 -0
  88. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/contents.rs +255 -0
  89. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/graph.rs +785 -0
  90. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/identifiers.rs +95 -0
  91. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/mod.rs +8 -0
  92. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest/tests/semantic_layer.rs +141 -0
  93. dlin_cli-0.2.5/crates/dlin-core/src/parser/manifest_cache.rs +307 -0
  94. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/parser/mod.rs +1 -1
  95. dlin_cli-0.2.5/crates/dlin-core/src/parser/project.rs +753 -0
  96. dlin_cli-0.2.5/crates/dlin-core/src/parser/sql/mod.rs +334 -0
  97. dlin_cli-0.2.5/crates/dlin-core/src/parser/sql/recovery.rs +246 -0
  98. dlin_cli-0.2.5/crates/dlin-core/src/parser/sql/tests.rs +1078 -0
  99. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/column_graph.rs +2 -491
  100. dlin_cli-0.2.5/crates/dlin-core/src/render/column_graph_tests.rs +489 -0
  101. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/tests/column_lineage_test.rs +29 -61
  102. dlin_cli-0.2.4rc3/crates/dlin/src/cli.rs +0 -2429
  103. dlin_cli-0.2.4rc3/crates/dlin/src/main.rs +0 -1736
  104. dlin_cli-0.2.4rc3/crates/dlin/src/mcp.rs +0 -1454
  105. dlin_cli-0.2.4rc3/crates/dlin/tests/integration_test.rs +0 -2812
  106. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/builder/tests/build_graph.rs +0 -1077
  107. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/cache.rs +0 -305
  108. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/tests/backend_regression.rs +0 -1329
  109. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/tests/cache.rs +0 -546
  110. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/tests/core_cross_model.rs +0 -282
  111. dlin_cli-0.2.4rc3/crates/dlin-core/src/graph/column_lineage/types.rs +0 -174
  112. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/cache.rs +0 -497
  113. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/jinja.rs +0 -753
  114. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/manifest.rs +0 -1879
  115. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/manifest_cache.rs +0 -207
  116. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/project.rs +0 -228
  117. dlin_cli-0.2.4rc3/crates/dlin-core/src/parser/sql.rs +0 -829
  118. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/LICENSE +0 -0
  119. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/builder/tests/generic_tests.rs +0 -0
  120. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/builder/tests/mod.rs +0 -0
  121. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/builder/tests/ref_parsing.rs +0 -0
  122. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/catalog.rs +0 -0
  123. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/catalog_provider.rs +0 -0
  124. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/dialect.rs +0 -0
  125. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/backend/types.rs +0 -0
  126. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/relation.rs +0 -0
  127. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/alias.rs +0 -0
  128. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/core_basic.rs +0 -0
  129. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/core_star_chain.rs +0 -0
  130. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/column_lineage/tests/mod.rs +0 -0
  131. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/collapse.rs +0 -0
  132. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/mod.rs +0 -0
  133. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/output.rs +0 -0
  134. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/search.rs +0 -0
  135. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot.snap +0 -0
  136. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_bfs_pseudoendpoint.snap +0 -0
  137. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_fan_out.snap +0 -0
  138. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_leaf_model.snap +0 -0
  139. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_multiple_focus_models.snap +0 -0
  140. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_no_source_exposure.snap +0 -0
  141. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_preserve_focus.snap +0 -0
  142. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_node_type_filter.snap +0 -0
  143. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_filter.snap +0 -0
  144. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_with_node_type.snap +0 -0
  145. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/transitive.rs +0 -0
  146. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/filter/tests/versioned.rs +0 -0
  147. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/impact.rs +0 -0
  148. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/graph/mod.rs +0 -0
  149. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/lib.rs +0 -0
  150. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/parser/columns.rs +0 -0
  151. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/parser/yaml_schema.rs +0 -0
  152. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/ascii.rs +0 -0
  153. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/dot.rs +0 -0
  154. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/html.rs +0 -0
  155. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/impact.rs +0 -0
  156. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/json.rs +0 -0
  157. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/layout.rs +0 -0
  158. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/list.rs +0 -0
  159. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/mermaid.rs +0 -0
  160. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/mod.rs +0 -0
  161. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/plain.rs +0 -0
  162. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_all_transformation_types.snap +0 -0
  163. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_escapes_special_chars.snap +0 -0
  164. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_id_collision_avoided.snap +0 -0
  165. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_indirect.snap +0 -0
  166. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_single.snap +0 -0
  167. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_single_model.snap +0 -0
  168. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_via_path.snap +0 -0
  169. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid.snap +0 -0
  170. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid_indirect_edge_label.snap +0 -0
  171. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain.snap +0 -0
  172. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_multi_hop.snap +0 -0
  173. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_non_direct_intermediate.snap +0 -0
  174. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_dotted_table_name.snap +0 -0
  175. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_id_collision_avoided.snap +0 -0
  176. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_label_escaping.snap +0 -0
  177. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_single_model.snap +0 -0
  178. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_model_path_non_direct_annotation.snap +0 -0
  179. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_no_sources.snap +0 -0
  180. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_single_model.snap +0 -0
  181. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__group_by_node_type.snap +0 -0
  182. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_all_edge_types.snap +0 -0
  183. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb.snap +0 -0
  184. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
  185. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_group_by_directory.snap +0 -0
  186. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_lineage.snap +0 -0
  187. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_transitive_edges.snap +0 -0
  188. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__html__tests__snapshot_html_json.snap +0 -0
  189. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json.snap +0 -0
  190. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
  191. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text.snap +0 -0
  192. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
  193. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_json_with_sql.snap +0 -0
  194. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_lineage.snap +0 -0
  195. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_node_metadata.snap +0 -0
  196. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_json.snap +0 -0
  197. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_plain.snap +0 -0
  198. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__group_by_node_type.snap +0 -0
  199. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
  200. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
  201. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_lineage.snap +0 -0
  202. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_single_model.snap +0 -0
  203. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
  204. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
  205. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
  206. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
  207. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
  208. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_lineage.snap +0 -0
  209. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
  210. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__plain__tests__snapshot_plain.snap +0 -0
  211. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_json.snap +0 -0
  212. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_text.snap +0 -0
  213. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/summary.rs +0 -0
  214. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/crates/dlin-core/src/render/svg.rs +0 -0
  215. {dlin_cli-0.2.4rc3 → dlin_cli-0.2.5}/pyproject.toml +0 -0
@@ -230,12 +230,13 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
230
230
 
231
231
  [[package]]
232
232
  name = "dlin"
233
- version = "0.2.4-rc.3"
233
+ version = "0.2.5"
234
234
  dependencies = [
235
235
  "anyhow",
236
236
  "clap",
237
237
  "dlin-core",
238
238
  "filetime",
239
+ "insta",
239
240
  "libc",
240
241
  "path-slash",
241
242
  "regex",
@@ -247,11 +248,12 @@ dependencies = [
247
248
 
248
249
  [[package]]
249
250
  name = "dlin-core"
250
- version = "0.2.4-rc.3"
251
+ version = "0.2.5"
251
252
  dependencies = [
252
253
  "anyhow",
253
254
  "clap",
254
255
  "colored",
256
+ "filetime",
255
257
  "globset",
256
258
  "indexmap",
257
259
  "insta",
@@ -413,9 +415,9 @@ dependencies = [
413
415
 
414
416
  [[package]]
415
417
  name = "granit-parser"
416
- version = "1.0.1"
418
+ version = "1.1.0"
417
419
  source = "registry+https://github.com/rust-lang/crates.io-index"
418
- checksum = "7c92814c286f45b5ed1498ce9547bc9637b473eba7037f8aee6a4d5a3c1e051c"
420
+ checksum = "4ccd1be9ebf2bd5520dbfcfb72b70ef492f654061299a097056f3e73410e38ec"
419
421
  dependencies = [
420
422
  "arraydeque",
421
423
  "smallvec",
@@ -761,9 +763,9 @@ dependencies = [
761
763
 
762
764
  [[package]]
763
765
  name = "serde-saphyr"
764
- version = "1.0.1"
766
+ version = "1.1.0"
765
767
  source = "registry+https://github.com/rust-lang/crates.io-index"
766
- checksum = "af2c6921c8ce48fb1b052b457619d008834039d80325992ed3bc55bbe6c155ad"
768
+ checksum = "a1ec1f5cac0eb96063c64b28705255a7ed6e7d77f95c1d25e9f8b8c928006ce1"
767
769
  dependencies = [
768
770
  "annotate-snippets",
769
771
  "base64",
@@ -861,7 +863,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
861
863
  [[package]]
862
864
  name = "sqllineage"
863
865
  version = "0.2.0"
864
- source = "git+https://github.com/funcpp/sqllineage.git?rev=4f6be31ce421af49c7dc87fb22e2b8d6c0156b57#4f6be31ce421af49c7dc87fb22e2b8d6c0156b57"
866
+ source = "git+https://github.com/funcpp/sqllineage.git?rev=b010d8083c60aee977055ea36f8a6807c1d51c62#b010d8083c60aee977055ea36f8a6807c1d51c62"
865
867
  dependencies = [
866
868
  "serde",
867
869
  "serde_json",
@@ -3,7 +3,7 @@ members = ["crates/*"]
3
3
  resolver = "3"
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.4-rc.3"
6
+ version = "0.2.5"
7
7
  edition = "2024"
8
8
  license = "MIT"
9
9
  repository = "https://github.com/eitsupi/dlin"
@@ -23,7 +23,7 @@ indexmap = "2"
23
23
  minijinja = "2"
24
24
  rayon = "1"
25
25
  globset = "0.4"
26
- sqllineage = { git = "https://github.com/funcpp/sqllineage.git", rev = "4f6be31ce421af49c7dc87fb22e2b8d6c0156b57", default-features = false }
26
+ sqllineage = { git = "https://github.com/funcpp/sqllineage.git", rev = "b010d8083c60aee977055ea36f8a6807c1d51c62", default-features = false }
27
27
  # Must stay in lockstep with the sqlparser version sqllineage depends on; see
28
28
  # `sqlparser_version_matches_sqllineage` in dlin-core.
29
29
  sqlparser = { version = "0.62", features = ["serde", "visitor"] }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dlin-cli
3
- Version: 0.2.4rc3
3
+ Version: 0.2.5
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -30,7 +30,7 @@ dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.j
30
30
 
31
31
  Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
32
32
 
33
- Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
33
+ Column-level lineage (`dlin column upstream` / `dlin column downstream`) requires a compiled `manifest.json` and is usable in practice while remaining Experimental for coverage reasons.
34
34
 
35
35
  ## Motivation
36
36
 
@@ -40,7 +40,7 @@ dlin is designed to fill that gap: a CLI tool that lets AI agents understand a d
40
40
 
41
41
  To replace `grep`, speed and size matter. dlin is a small, self-contained binary with no runtime dependencies. It parses SQL directly, evaluates common Jinja patterns without Python, parallelizes file I/O, and caches aggressively.
42
42
 
43
- The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage as fast as possible, and also offers experimental column-level lineage for deeper analysis.
43
+ The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage fast and provides column-level lineage for deeper analysis.
44
44
 
45
45
  ## Install
46
46
 
@@ -94,9 +94,9 @@ git diff --name-only main | dlin graph -o json
94
94
 
95
95
  dlin supports two source modes for model-level commands.
96
96
 
97
- **SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
97
+ **SQL parse mode (default)** is for developers editing a live dbt project. It reads `ref()` and `source()` directly from SQL without waiting for `dbt compile`, so model-level lineage quickly identifies the related models. Read the relevant SQL for exact transformation behavior.
98
98
 
99
- **Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
99
+ **Manifest mode** (`--source manifest`) is for analysts or agents analyzing compiled state rather than editing live SQL. A developer compiles once and shares `manifest.json`; users explore the resolved graph without SQL or Python. Use column-level lineage when a field-level trace is needed; it requires the compiled manifest.
100
100
 
101
101
  ```sh
102
102
  # SQL parse mode: reads SQL files directly (default)
@@ -111,7 +111,7 @@ For model-name inputs, `manifest.json` is the only file needed in manifest mode.
111
111
 
112
112
  ### Limitations of SQL parse mode
113
113
 
114
- - `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
114
+ - `var()` resolves from `vars.yml` or `dbt_project.yml` (`--vars` CLI overrides not supported)
115
115
  - Runtime context (`target.type`, `env_var()`) is not evaluated
116
116
  - Conditional Jinja branches use default values; non-default paths may be missed
117
117
  - Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
@@ -168,7 +168,7 @@ Pass `--dialect` to match your project's SQL dialect for accurate column lineage
168
168
  - **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
169
169
  - **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
170
170
  - **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
171
- - **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
171
+ - **Column-level lineage** (experimental): traces columns across models with transformation classification through the Rust lineage backend; requires `manifest.json`
172
172
 
173
173
  ## Mermaid diagrams
174
174
 
@@ -304,10 +304,7 @@ Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.
304
304
 
305
305
  ## Column-level lineage (Experimental)
306
306
 
307
- > [!WARNING]
308
- > Column-level lineage uses [sqllineage](https://github.com/funcpp/sqllineage) for SQL parsing and lineage extraction. The production backend directly supports Generic, PostgreSQL, MySQL, Hive, Databricks, Snowflake, BigQuery, DuckDB, SQLite, Spark, Trino, Redshift, T-SQL, and ClickHouse. The `dlin` CLI and MCP resolve other recognized dialects to Generic with a warning; direct `dlin-core` API callers receive an unsupported-dialect error instead. Coverage still varies by SQL complexity and dialect, and patterns such as `SELECT *` chains, STRUCT expansion, and some database-specific syntax may remain unresolved.
309
-
310
- `dlin column upstream` and `dlin column downstream` trace columns across models. Unlike model-level commands, they always require a compiled `manifest.json`. Run `dbt compile` first.
307
+ `dlin column upstream` and `dlin column downstream` trace columns across models. They require a compiled `manifest.json`, so run `dbt compile` first. Regression fixtures and real dbt project validation show that column-level lineage is usable in practice. Experimental reflects the Rust stack's shorter production history and remaining cross-dialect and complex-SQL coverage gaps, not a prototype-only status.
311
308
 
312
309
  ```sh
313
310
  # Where does each output column of orders come from?
@@ -424,6 +421,18 @@ flowchart LR
424
421
 
425
422
  `stg_orders.order_id` flows directly into `orders.order_id` and `order_enriched.order_id`. `orders.order_id` is then aggregated into `customers.order_count`. Each edge shows its per-hop transformation type.
426
423
 
424
+ ### Performance benchmark
425
+
426
+ Correctness-gated means from the synthetic scalability run (3 runs, 1 warmup):
427
+
428
+ | Workload | dlin 0.2.4 | [Parrant 0.17.2](https://pypi.org/project/parrant/0.17.2/) | [dbt-meta 0.3.8](https://pypi.org/project/dbt-meta/0.3.8/) |
429
+ | --- | ---: | ---: | ---: |
430
+ | Volume, 100,150 columns, single upstream | 88.9 ms | 37.4 s | build >120 s timeout; query not run |
431
+ | Deep 64, single upstream | 115 ms | 1.42 s | build 4.86 s; query 411 ms |
432
+ | Fan-out 128, downstream | 114 ms | 1.78 s | build 6.47 s; query 363 ms |
433
+
434
+ These synthetic results use artifacts derived from the real dbt fixture. Native Rust avoids Python startup and dlin showed lower latency here; dlin uses `--no-cache`, Parrant includes parsing, and dbt-meta query excludes build. They are not a general ranking; see the [full results and reproduction](benchmarks/column-lineage/results/published/scalability/summary.md).
435
+
427
436
  ### Known limitations
428
437
 
429
438
  - **Requires `dbt compile`**: no SQL parse mode fallback; manifest with compiled SQL is always needed
@@ -8,7 +8,7 @@ dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.j
8
8
 
9
9
  Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
10
10
 
11
- Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
11
+ Column-level lineage (`dlin column upstream` / `dlin column downstream`) requires a compiled `manifest.json` and is usable in practice while remaining Experimental for coverage reasons.
12
12
 
13
13
  ## Motivation
14
14
 
@@ -18,7 +18,7 @@ dlin is designed to fill that gap: a CLI tool that lets AI agents understand a d
18
18
 
19
19
  To replace `grep`, speed and size matter. dlin is a small, self-contained binary with no runtime dependencies. It parses SQL directly, evaluates common Jinja patterns without Python, parallelizes file I/O, and caches aggressively.
20
20
 
21
- The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage as fast as possible, and also offers experimental column-level lineage for deeper analysis.
21
+ The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage fast and provides column-level lineage for deeper analysis.
22
22
 
23
23
  ## Install
24
24
 
@@ -72,9 +72,9 @@ git diff --name-only main | dlin graph -o json
72
72
 
73
73
  dlin supports two source modes for model-level commands.
74
74
 
75
- **SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
75
+ **SQL parse mode (default)** is for developers editing a live dbt project. It reads `ref()` and `source()` directly from SQL without waiting for `dbt compile`, so model-level lineage quickly identifies the related models. Read the relevant SQL for exact transformation behavior.
76
76
 
77
- **Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
77
+ **Manifest mode** (`--source manifest`) is for analysts or agents analyzing compiled state rather than editing live SQL. A developer compiles once and shares `manifest.json`; users explore the resolved graph without SQL or Python. Use column-level lineage when a field-level trace is needed; it requires the compiled manifest.
78
78
 
79
79
  ```sh
80
80
  # SQL parse mode: reads SQL files directly (default)
@@ -89,7 +89,7 @@ For model-name inputs, `manifest.json` is the only file needed in manifest mode.
89
89
 
90
90
  ### Limitations of SQL parse mode
91
91
 
92
- - `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
92
+ - `var()` resolves from `vars.yml` or `dbt_project.yml` (`--vars` CLI overrides not supported)
93
93
  - Runtime context (`target.type`, `env_var()`) is not evaluated
94
94
  - Conditional Jinja branches use default values; non-default paths may be missed
95
95
  - Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
@@ -146,7 +146,7 @@ Pass `--dialect` to match your project's SQL dialect for accurate column lineage
146
146
  - **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
147
147
  - **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
148
148
  - **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
149
- - **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
149
+ - **Column-level lineage** (experimental): traces columns across models with transformation classification through the Rust lineage backend; requires `manifest.json`
150
150
 
151
151
  ## Mermaid diagrams
152
152
 
@@ -282,10 +282,7 @@ Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.
282
282
 
283
283
  ## Column-level lineage (Experimental)
284
284
 
285
- > [!WARNING]
286
- > Column-level lineage uses [sqllineage](https://github.com/funcpp/sqllineage) for SQL parsing and lineage extraction. The production backend directly supports Generic, PostgreSQL, MySQL, Hive, Databricks, Snowflake, BigQuery, DuckDB, SQLite, Spark, Trino, Redshift, T-SQL, and ClickHouse. The `dlin` CLI and MCP resolve other recognized dialects to Generic with a warning; direct `dlin-core` API callers receive an unsupported-dialect error instead. Coverage still varies by SQL complexity and dialect, and patterns such as `SELECT *` chains, STRUCT expansion, and some database-specific syntax may remain unresolved.
287
-
288
- `dlin column upstream` and `dlin column downstream` trace columns across models. Unlike model-level commands, they always require a compiled `manifest.json`. Run `dbt compile` first.
285
+ `dlin column upstream` and `dlin column downstream` trace columns across models. They require a compiled `manifest.json`, so run `dbt compile` first. Regression fixtures and real dbt project validation show that column-level lineage is usable in practice. Experimental reflects the Rust stack's shorter production history and remaining cross-dialect and complex-SQL coverage gaps, not a prototype-only status.
289
286
 
290
287
  ```sh
291
288
  # Where does each output column of orders come from?
@@ -402,6 +399,18 @@ flowchart LR
402
399
 
403
400
  `stg_orders.order_id` flows directly into `orders.order_id` and `order_enriched.order_id`. `orders.order_id` is then aggregated into `customers.order_count`. Each edge shows its per-hop transformation type.
404
401
 
402
+ ### Performance benchmark
403
+
404
+ Correctness-gated means from the synthetic scalability run (3 runs, 1 warmup):
405
+
406
+ | Workload | dlin 0.2.4 | [Parrant 0.17.2](https://pypi.org/project/parrant/0.17.2/) | [dbt-meta 0.3.8](https://pypi.org/project/dbt-meta/0.3.8/) |
407
+ | --- | ---: | ---: | ---: |
408
+ | Volume, 100,150 columns, single upstream | 88.9 ms | 37.4 s | build >120 s timeout; query not run |
409
+ | Deep 64, single upstream | 115 ms | 1.42 s | build 4.86 s; query 411 ms |
410
+ | Fan-out 128, downstream | 114 ms | 1.78 s | build 6.47 s; query 363 ms |
411
+
412
+ These synthetic results use artifacts derived from the real dbt fixture. Native Rust avoids Python startup and dlin showed lower latency here; dlin uses `--no-cache`, Parrant includes parsing, and dbt-meta query excludes build. They are not a general ranking; see the [full results and reproduction](benchmarks/column-lineage/results/published/scalability/summary.md).
413
+
405
414
  ### Known limitations
406
415
 
407
416
  - **Requires `dbt compile`**: no SQL parse mode fallback; manifest with compiled SQL is always needed
@@ -33,6 +33,7 @@ tempfile = { workspace = true }
33
33
  regex = { workspace = true }
34
34
  serde_json = { workspace = true }
35
35
  serde-saphyr = { workspace = true }
36
+ insta = { workspace = true }
36
37
 
37
38
  [lints]
38
39
  workspace = true
@@ -8,7 +8,7 @@ dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.j
8
8
 
9
9
  Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
10
10
 
11
- Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
11
+ Column-level lineage (`dlin column upstream` / `dlin column downstream`) requires a compiled `manifest.json` and is usable in practice while remaining Experimental for coverage reasons.
12
12
 
13
13
  ## Motivation
14
14
 
@@ -18,7 +18,7 @@ dlin is designed to fill that gap: a CLI tool that lets AI agents understand a d
18
18
 
19
19
  To replace `grep`, speed and size matter. dlin is a small, self-contained binary with no runtime dependencies. It parses SQL directly, evaluates common Jinja patterns without Python, parallelizes file I/O, and caches aggressively.
20
20
 
21
- The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage as fast as possible, and also offers experimental column-level lineage for deeper analysis.
21
+ The key idea behind dlin is that finding the right models fast is what matters most. The hard part for agents is knowing which models to look at in the first place. dlin focuses on making model-level lineage fast and provides column-level lineage for deeper analysis.
22
22
 
23
23
  ## Install
24
24
 
@@ -72,9 +72,9 @@ git diff --name-only main | dlin graph -o json
72
72
 
73
73
  dlin supports two source modes for model-level commands.
74
74
 
75
- **SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
75
+ **SQL parse mode (default)** is for developers editing a live dbt project. It reads `ref()` and `source()` directly from SQL without waiting for `dbt compile`, so model-level lineage quickly identifies the related models. Read the relevant SQL for exact transformation behavior.
76
76
 
77
- **Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
77
+ **Manifest mode** (`--source manifest`) is for analysts or agents analyzing compiled state rather than editing live SQL. A developer compiles once and shares `manifest.json`; users explore the resolved graph without SQL or Python. Use column-level lineage when a field-level trace is needed; it requires the compiled manifest.
78
78
 
79
79
  ```sh
80
80
  # SQL parse mode: reads SQL files directly (default)
@@ -89,7 +89,7 @@ For model-name inputs, `manifest.json` is the only file needed in manifest mode.
89
89
 
90
90
  ### Limitations of SQL parse mode
91
91
 
92
- - `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
92
+ - `var()` resolves from `vars.yml` or `dbt_project.yml` (`--vars` CLI overrides not supported)
93
93
  - Runtime context (`target.type`, `env_var()`) is not evaluated
94
94
  - Conditional Jinja branches use default values; non-default paths may be missed
95
95
  - Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
@@ -146,7 +146,7 @@ Pass `--dialect` to match your project's SQL dialect for accurate column lineage
146
146
  - **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
147
147
  - **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
148
148
  - **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
149
- - **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
149
+ - **Column-level lineage** (experimental): traces columns across models with transformation classification through the Rust lineage backend; requires `manifest.json`
150
150
 
151
151
  ## Mermaid diagrams
152
152
 
@@ -282,10 +282,7 @@ Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.
282
282
 
283
283
  ## Column-level lineage (Experimental)
284
284
 
285
- > [!WARNING]
286
- > Column-level lineage uses [sqllineage](https://github.com/funcpp/sqllineage) for SQL parsing and lineage extraction. The production backend directly supports Generic, PostgreSQL, MySQL, Hive, Databricks, Snowflake, BigQuery, DuckDB, SQLite, Spark, Trino, Redshift, T-SQL, and ClickHouse. The `dlin` CLI and MCP resolve other recognized dialects to Generic with a warning; direct `dlin-core` API callers receive an unsupported-dialect error instead. Coverage still varies by SQL complexity and dialect, and patterns such as `SELECT *` chains, STRUCT expansion, and some database-specific syntax may remain unresolved.
287
-
288
- `dlin column upstream` and `dlin column downstream` trace columns across models. Unlike model-level commands, they always require a compiled `manifest.json`. Run `dbt compile` first.
285
+ `dlin column upstream` and `dlin column downstream` trace columns across models. They require a compiled `manifest.json`, so run `dbt compile` first. Regression fixtures and real dbt project validation show that column-level lineage is usable in practice. Experimental reflects the Rust stack's shorter production history and remaining cross-dialect and complex-SQL coverage gaps, not a prototype-only status.
289
286
 
290
287
  ```sh
291
288
  # Where does each output column of orders come from?
@@ -402,6 +399,18 @@ flowchart LR
402
399
 
403
400
  `stg_orders.order_id` flows directly into `orders.order_id` and `order_enriched.order_id`. `orders.order_id` is then aggregated into `customers.order_count`. Each edge shows its per-hop transformation type.
404
401
 
402
+ ### Performance benchmark
403
+
404
+ Correctness-gated means from the synthetic scalability run (3 runs, 1 warmup):
405
+
406
+ | Workload | dlin 0.2.4 | [Parrant 0.17.2](https://pypi.org/project/parrant/0.17.2/) | [dbt-meta 0.3.8](https://pypi.org/project/dbt-meta/0.3.8/) |
407
+ | --- | ---: | ---: | ---: |
408
+ | Volume, 100,150 columns, single upstream | 88.9 ms | 37.4 s | build >120 s timeout; query not run |
409
+ | Deep 64, single upstream | 115 ms | 1.42 s | build 4.86 s; query 411 ms |
410
+ | Fan-out 128, downstream | 114 ms | 1.78 s | build 6.47 s; query 363 ms |
411
+
412
+ These synthetic results use artifacts derived from the real dbt fixture. Native Rust avoids Python startup and dlin showed lower latency here; dlin uses `--no-cache`, Parrant includes parsing, and dbt-meta query excludes build. They are not a general ranking; see the [full results and reproduction](benchmarks/column-lineage/results/published/scalability/summary.md).
413
+
405
414
  ### Known limitations
406
415
 
407
416
  - **Requires `dbt compile`**: no SQL parse mode fallback; manifest with compiled SQL is always needed
@@ -0,0 +1,240 @@
1
+ use std::path::PathBuf;
2
+
3
+ use super::*;
4
+ use clap::Subcommand;
5
+
6
+ #[derive(Debug, clap::Args)]
7
+ pub struct ColumnArgs {
8
+ #[command(subcommand)]
9
+ pub command: ColumnCommand,
10
+ }
11
+
12
+ #[derive(Debug, Subcommand)]
13
+ pub enum ColumnCommand {
14
+ /// Compute column-level lineage for a model (traces upstream sources)
15
+ #[command(
16
+ long_about = "\
17
+ Compute column-level lineage for one or more models.
18
+
19
+ Direction: upstream only. Traces backward from a model's output columns to
20
+ their raw source columns across the full DAG. There are no -u/-d depth flags
21
+ — the entire upstream chain is always traversed automatically.
22
+
23
+ To find what downstream models or columns would be affected by changing a
24
+ specific column, use `dlin column downstream` instead.
25
+
26
+ There is no --source flag; manifest.json is the only data source (unlike
27
+ `dlin graph` which supports both SQL files and manifest).
28
+
29
+ Requires manifest.json with compiled SQL (run `dbt compile` first).
30
+ Use `dlin check-manifest` to verify freshness before querying.
31
+
32
+ Column resolution order:
33
+ 1. YAML column definitions (schema.yml / models.yml)
34
+ 2. SQL inference from compiled_code (fallback when YAML is absent)
35
+
36
+ Stdin/pipe support:
37
+ Accepts model names or file paths on stdin (one per line).
38
+ File paths (detected by extension or path separator) are resolved to
39
+ model names using the dbt project configuration.
40
+
41
+ Output format (-o/--output):
42
+ json (default) JSON array per model with the following structure:
43
+ model model name
44
+ traced_columns number of columns successfully traced
45
+ total_columns total number of columns attempted
46
+ columns[]
47
+ column output column name
48
+ transformation how the column was derived:
49
+ direct passed through unchanged (including renames)
50
+ aggregation aggregate function (SUM, COUNT, etc.)
51
+ expression arithmetic or other expression
52
+ cast type cast (CAST(x AS INT))
53
+ conditional CASE WHEN expression
54
+ unknown could not classify
55
+ sources[]
56
+ table source model or raw table name; empty string (\"\") when the
57
+ value originates from a literal (NULL, constant, UNNEST, etc.)
58
+ — rendered as \"(literal)\" in plain/mermaid/dot outputs
59
+ column source column name
60
+ model_path[] intermediate [model, column, transformation] triples traversed (omitted if empty)
61
+ errors[] parse or resolution diagnostics. An indeterminate per-column
62
+ diagnostic is non-fatal and does not change the exit code;
63
+ model-level, missing-column, ambiguous, and parse diagnostics
64
+ are fatal (exit code 1).
65
+ plain human-readable text, one model per block
66
+ mermaid Mermaid flowchart (LR) with subgraphs per model
67
+ dot Graphviz DOT format; models as clusters, columns as nodes
68
+ color-coded by transformation type (pipe to `dot -Tsvg`)
69
+
70
+ Exit codes:
71
+ 0 Success
72
+ 1 Error (model not found, no manifest, fatal analysis errors, etc.)",
73
+ after_long_help = "\
74
+ Examples:
75
+ # Column lineage for a single model (JSON output)
76
+ dlin column upstream orders
77
+
78
+ # Human-readable plain output
79
+ dlin column upstream orders -o plain
80
+
81
+ # Mermaid flowchart
82
+ dlin column upstream orders -o mermaid
83
+
84
+ # Specific columns only
85
+ dlin column upstream orders --column order_id --column status
86
+
87
+ # Multiple models
88
+ dlin column upstream orders stg_orders
89
+
90
+ # With explicit manifest path
91
+ dlin column upstream orders --manifest-path target/manifest.json
92
+
93
+ # BigQuery project
94
+ dlin column upstream orders --dialect bigquery
95
+
96
+ # From git diff (pipe changed files)
97
+ git diff --name-only main | dlin column upstream -o json"
98
+ )]
99
+ Upstream(ColumnGraphArgs),
100
+
101
+ /// Analyze downstream column-level impact of changing a column
102
+ #[command(
103
+ long_about = "\
104
+ Analyze downstream column-level impact of changing a column.
105
+
106
+ Direction: downstream only. Starting from a specific column, follows forward
107
+ edges to find all dependent models and columns. There are no -u/-d depth flags
108
+ — all downstream dependents are always included.
109
+
110
+ This is the reverse direction of `dlin column upstream` (which traces upstream
111
+ sources). To trace where a column's data comes from, use `dlin column upstream`.
112
+
113
+ Takes a single model and one or more --column flags (required).
114
+
115
+ There is no --source flag; manifest.json is the only data source (unlike
116
+ `dlin graph`/`dlin impact` which support both SQL files and manifest).
117
+
118
+ Requires compiled SQL in manifest.json — run `dbt compile` first.
119
+ Use `dlin check-manifest` to verify freshness before querying.
120
+
121
+ Output format (-o/--output):
122
+ json (default) JSON array per column with affected downstream columns and models
123
+ plain human-readable text, one source column per block
124
+ mermaid Mermaid flowchart (LR) showing impacted columns across models
125
+ dot Graphviz DOT format; models as clusters, columns as nodes
126
+ color-coded by transformation type (pipe to `dot -Tsvg`)
127
+
128
+ Exit codes:
129
+ 0 Success
130
+ 1 Error (model not found, no manifest, fatal analysis errors, etc.)",
131
+ after_long_help = "\
132
+ Examples:
133
+ # Impact of changing a single column (JSON output)
134
+ dlin column downstream stg_orders --column order_id
135
+
136
+ # Human-readable plain output
137
+ dlin column downstream stg_orders --column order_id -o plain
138
+
139
+ # Mermaid flowchart
140
+ dlin column downstream stg_orders --column order_id -o mermaid
141
+
142
+ # Impact of multiple columns
143
+ dlin column downstream stg_orders --column order_id --column status
144
+
145
+ # With explicit manifest path
146
+ dlin column downstream stg_orders --column order_id --manifest-path target/manifest.json
147
+
148
+ # BigQuery project
149
+ dlin column downstream stg_orders --column order_id --dialect bigquery"
150
+ )]
151
+ Downstream(ColumnImpactArgs),
152
+ }
153
+
154
+ #[derive(Debug, clap::Args)]
155
+ pub struct ColumnGraphArgs {
156
+ /// Model names or file paths to analyze column lineage for (also accepts stdin)
157
+ pub model: Vec<String>,
158
+
159
+ /// Specific columns to analyze (analyzes all columns if omitted)
160
+ #[arg(long)]
161
+ pub column: Vec<String>,
162
+
163
+ /// Output format: json (default), plain, mermaid
164
+ #[arg(short = 'o', long, default_value = "json")]
165
+ pub output: ColumnOutputFormat,
166
+
167
+ /// SQL dialect for parsing compiled SQL.
168
+ /// Auto-detected from manifest.metadata.adapter_type when omitted. Recognized dialects
169
+ /// removed from the active backend fall back to Generic with a warning.
170
+ #[arg(long, value_parser = parse_dialect_arg)]
171
+ pub dialect: Option<DialectArg>,
172
+
173
+ /// Path to dbt project directory
174
+ #[arg(short = 'p', long = "project-dir", default_value = ".")]
175
+ pub project_dir: PathBuf,
176
+
177
+ /// Path to manifest.json file or directory containing target/manifest.json (default: <project-dir>/target/manifest.json)
178
+ #[arg(long)]
179
+ pub manifest_path: Option<PathBuf>,
180
+
181
+ /// Directory for caching column lineage results (default: <project-dir>/.dlin_cache)
182
+ #[arg(long, env = "DLIN_CACHE_DIR")]
183
+ pub cache_dir: Option<PathBuf>,
184
+
185
+ /// Disable column lineage cache
186
+ #[arg(long, env = "DLIN_NO_CACHE")]
187
+ pub no_cache: bool,
188
+
189
+ /// Discard existing cache and rebuild from scratch
190
+ #[arg(long, env = "DLIN_REFRESH_CACHE", conflicts_with = "no_cache")]
191
+ pub refresh_cache: bool,
192
+
193
+ /// Suppress warning messages
194
+ #[arg(short = 'q', long)]
195
+ pub quiet: bool,
196
+ }
197
+
198
+ #[derive(Debug, clap::Args)]
199
+ pub struct ColumnImpactArgs {
200
+ /// Model name to analyze column downstream impact for
201
+ pub model: String,
202
+
203
+ /// Columns to analyze impact for (required)
204
+ #[arg(long, required = true)]
205
+ pub column: Vec<String>,
206
+
207
+ /// Output format: json (default), plain, mermaid
208
+ #[arg(short = 'o', long, default_value = "json")]
209
+ pub output: ColumnOutputFormat,
210
+
211
+ /// SQL dialect for parsing compiled SQL.
212
+ /// Auto-detected from manifest.metadata.adapter_type when omitted. Recognized dialects
213
+ /// removed from the active backend fall back to Generic with a warning.
214
+ #[arg(long, value_parser = parse_dialect_arg)]
215
+ pub dialect: Option<DialectArg>,
216
+
217
+ /// Path to dbt project directory
218
+ #[arg(short = 'p', long = "project-dir", default_value = ".")]
219
+ pub project_dir: PathBuf,
220
+
221
+ /// Path to manifest.json file or directory containing target/manifest.json (default: <project-dir>/target/manifest.json)
222
+ #[arg(long)]
223
+ pub manifest_path: Option<PathBuf>,
224
+
225
+ /// Directory for caching column lineage results (default: <project-dir>/.dlin_cache)
226
+ #[arg(long, env = "DLIN_CACHE_DIR")]
227
+ pub cache_dir: Option<PathBuf>,
228
+
229
+ /// Disable column lineage cache
230
+ #[arg(long, env = "DLIN_NO_CACHE")]
231
+ pub no_cache: bool,
232
+
233
+ /// Discard existing cache and rebuild from scratch
234
+ #[arg(long, env = "DLIN_REFRESH_CACHE", conflicts_with = "no_cache")]
235
+ pub refresh_cache: bool,
236
+
237
+ /// Suppress warning messages
238
+ #[arg(short = 'q', long)]
239
+ pub quiet: bool,
240
+ }