dlin-cli 0.2.4b1__tar.gz → 0.2.4rc2__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 (139) hide show
  1. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/Cargo.lock +51 -40
  2. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/Cargo.toml +3 -3
  3. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/PKG-INFO +1 -1
  4. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/cross_model.rs +1 -8
  5. dlin_cli-0.2.4rc2/crates/dlin-core/src/graph/column_lineage/manifest_schema.rs +302 -0
  6. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/mod.rs +28 -8
  7. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/schema.rs +1 -65
  8. dlin_cli-0.2.4rc2/crates/dlin-core/src/graph/column_lineage/semantic_model.rs +377 -0
  9. dlin_cli-0.2.4rc2/crates/dlin-core/src/graph/column_lineage/single_model.rs +315 -0
  10. dlin_cli-0.2.4rc2/crates/dlin-core/src/graph/column_lineage/star_guard.rs +652 -0
  11. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/cache.rs +1 -1
  12. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/core_star.rs +483 -55
  13. dlin_cli-0.2.4rc2/crates/dlin-core/src/graph/column_lineage/tests/core_util.rs +137 -0
  14. dlin_cli-0.2.4b1/crates/dlin-core/src/graph/column_lineage/single_model.rs +0 -450
  15. dlin_cli-0.2.4b1/crates/dlin-core/src/graph/column_lineage/tests/core_util.rs +0 -33
  16. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/LICENSE +0 -0
  17. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/README.md +0 -0
  18. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/Cargo.toml +0 -0
  19. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/README.md +0 -0
  20. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/src/cli.rs +0 -0
  21. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/src/main.rs +0 -0
  22. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/src/mcp.rs +0 -0
  23. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin/tests/integration_test.rs +0 -0
  24. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/Cargo.toml +0 -0
  25. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/README.md +0 -0
  26. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/error.rs +0 -0
  27. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/mod.rs +0 -0
  28. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/tests/build_graph.rs +0 -0
  29. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/tests/generic_tests.rs +0 -0
  30. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/tests/mod.rs +0 -0
  31. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/tests/ref_parsing.rs +0 -0
  32. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/builder/tests/versioned.rs +0 -0
  33. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/cache.rs +0 -0
  34. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/impact.rs +0 -0
  35. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/core_basic.rs +0 -0
  36. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/core_cross_model.rs +0 -0
  37. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/impact.rs +0 -0
  38. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/tests/mod.rs +0 -0
  39. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/column_lineage/types.rs +0 -0
  40. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/mod.rs +0 -0
  41. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/collapse.rs +0 -0
  42. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/filter_graph.rs +0 -0
  43. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/mod.rs +0 -0
  44. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/output.rs +0 -0
  45. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/search.rs +0 -0
  46. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/selector.rs +0 -0
  47. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot.snap +0 -0
  48. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_bfs_pseudoendpoint.snap +0 -0
  49. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_fan_out.snap +0 -0
  50. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_leaf_model.snap +0 -0
  51. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_multiple_focus_models.snap +0 -0
  52. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_no_source_exposure.snap +0 -0
  53. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_preserve_focus.snap +0 -0
  54. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_node_type_filter.snap +0 -0
  55. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_filter.snap +0 -0
  56. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_with_node_type.snap +0 -0
  57. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/transitive.rs +0 -0
  58. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/filter/tests/versioned.rs +0 -0
  59. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/impact.rs +0 -0
  60. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/mod.rs +0 -0
  61. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/graph/types.rs +0 -0
  62. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/input.rs +0 -0
  63. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/lib.rs +0 -0
  64. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/cache.rs +0 -0
  65. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/columns.rs +0 -0
  66. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/discovery.rs +0 -0
  67. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/jinja.rs +0 -0
  68. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/manifest.rs +0 -0
  69. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/manifest_cache.rs +0 -0
  70. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/mod.rs +0 -0
  71. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/project.rs +0 -0
  72. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/sql.rs +0 -0
  73. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/parser/yaml_schema.rs +0 -0
  74. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/ascii.rs +0 -0
  75. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/column_graph.rs +0 -0
  76. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/dot.rs +0 -0
  77. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/html.rs +0 -0
  78. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/impact.rs +0 -0
  79. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/json.rs +0 -0
  80. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/layout.rs +0 -0
  81. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/list.rs +0 -0
  82. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/mermaid.rs +0 -0
  83. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/mod.rs +0 -0
  84. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/plain.rs +0 -0
  85. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_all_transformation_types.snap +0 -0
  86. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_escapes_special_chars.snap +0 -0
  87. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_id_collision_avoided.snap +0 -0
  88. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_indirect.snap +0 -0
  89. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_single.snap +0 -0
  90. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_single_model.snap +0 -0
  91. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_via_path.snap +0 -0
  92. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid.snap +0 -0
  93. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid_indirect_edge_label.snap +0 -0
  94. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain.snap +0 -0
  95. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_multi_hop.snap +0 -0
  96. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_non_direct_intermediate.snap +0 -0
  97. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_dotted_table_name.snap +0 -0
  98. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_id_collision_avoided.snap +0 -0
  99. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_label_escaping.snap +0 -0
  100. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_single_model.snap +0 -0
  101. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_model_path_non_direct_annotation.snap +0 -0
  102. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_no_sources.snap +0 -0
  103. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_single_model.snap +0 -0
  104. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__group_by_node_type.snap +0 -0
  105. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_all_edge_types.snap +0 -0
  106. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb.snap +0 -0
  107. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
  108. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_group_by_directory.snap +0 -0
  109. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_lineage.snap +0 -0
  110. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_transitive_edges.snap +0 -0
  111. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__html__tests__snapshot_html_json.snap +0 -0
  112. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json.snap +0 -0
  113. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
  114. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text.snap +0 -0
  115. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
  116. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_json_with_sql.snap +0 -0
  117. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_lineage.snap +0 -0
  118. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_node_metadata.snap +0 -0
  119. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_json.snap +0 -0
  120. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_plain.snap +0 -0
  121. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__group_by_node_type.snap +0 -0
  122. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
  123. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
  124. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_lineage.snap +0 -0
  125. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_single_model.snap +0 -0
  126. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
  127. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
  128. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
  129. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
  130. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
  131. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_lineage.snap +0 -0
  132. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
  133. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__plain__tests__snapshot_plain.snap +0 -0
  134. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_json.snap +0 -0
  135. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_text.snap +0 -0
  136. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/summary.rs +0 -0
  137. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/src/render/svg.rs +0 -0
  138. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/crates/dlin-core/tests/column_lineage_test.rs +0 -0
  139. {dlin_cli-0.2.4b1 → dlin_cli-0.2.4rc2}/pyproject.toml +0 -0
@@ -87,9 +87,9 @@ dependencies = [
87
87
 
88
88
  [[package]]
89
89
  name = "anyhow"
90
- version = "1.0.103"
90
+ version = "1.0.104"
91
91
  source = "registry+https://github.com/rust-lang/crates.io-index"
92
- checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
92
+ checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
93
93
 
94
94
  [[package]]
95
95
  name = "arraydeque"
@@ -139,9 +139,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
139
139
 
140
140
  [[package]]
141
141
  name = "clap"
142
- version = "4.6.1"
142
+ version = "4.6.4"
143
143
  source = "registry+https://github.com/rust-lang/crates.io-index"
144
- checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
144
+ checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7"
145
145
  dependencies = [
146
146
  "clap_builder",
147
147
  "clap_derive",
@@ -149,9 +149,9 @@ dependencies = [
149
149
 
150
150
  [[package]]
151
151
  name = "clap_builder"
152
- version = "4.6.0"
152
+ version = "4.6.2"
153
153
  source = "registry+https://github.com/rust-lang/crates.io-index"
154
- checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
154
+ checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b"
155
155
  dependencies = [
156
156
  "anstream",
157
157
  "anstyle",
@@ -161,14 +161,14 @@ dependencies = [
161
161
 
162
162
  [[package]]
163
163
  name = "clap_derive"
164
- version = "4.6.1"
164
+ version = "4.6.4"
165
165
  source = "registry+https://github.com/rust-lang/crates.io-index"
166
- checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
166
+ checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
167
167
  dependencies = [
168
168
  "heck",
169
169
  "proc-macro2",
170
170
  "quote",
171
- "syn",
171
+ "syn 3.0.3",
172
172
  ]
173
173
 
174
174
  [[package]]
@@ -230,7 +230,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
230
230
 
231
231
  [[package]]
232
232
  name = "dlin"
233
- version = "0.2.4-beta.1"
233
+ version = "0.2.4-rc.2"
234
234
  dependencies = [
235
235
  "anyhow",
236
236
  "clap",
@@ -247,7 +247,7 @@ dependencies = [
247
247
 
248
248
  [[package]]
249
249
  name = "dlin-core"
250
- version = "0.2.4-beta.1"
250
+ version = "0.2.4-rc.2"
251
251
  dependencies = [
252
252
  "anyhow",
253
253
  "clap",
@@ -266,7 +266,7 @@ dependencies = [
266
266
  "serde_json",
267
267
  "serial_test",
268
268
  "tempfile",
269
- "thiserror 2.0.18",
269
+ "thiserror 2.0.19",
270
270
  "walkdir",
271
271
  ]
272
272
 
@@ -385,9 +385,9 @@ dependencies = [
385
385
 
386
386
  [[package]]
387
387
  name = "globset"
388
- version = "0.4.18"
388
+ version = "0.4.19"
389
389
  source = "registry+https://github.com/rust-lang/crates.io-index"
390
- checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
390
+ checksum = "e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd"
391
391
  dependencies = [
392
392
  "aho-corasick",
393
393
  "bstr",
@@ -473,9 +473,9 @@ dependencies = [
473
473
 
474
474
  [[package]]
475
475
  name = "libc"
476
- version = "0.2.186"
476
+ version = "0.2.189"
477
477
  source = "registry+https://github.com/rust-lang/crates.io-index"
478
- checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
478
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
479
479
 
480
480
  [[package]]
481
481
  name = "linux-raw-sys"
@@ -597,9 +597,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
597
597
 
598
598
  [[package]]
599
599
  name = "polyglot-sql"
600
- version = "0.6.2"
600
+ version = "0.8.0"
601
601
  source = "registry+https://github.com/rust-lang/crates.io-index"
602
- checksum = "009cbd62f8c82de46697221ee66b0cf3a6dacbda16f8c5a2ce25853940073bd5"
602
+ checksum = "6b7dd6da530087bffbf2b8b791914093b669f70eac07dbc66cf08f6954a1902e"
603
603
  dependencies = [
604
604
  "polyglot-sql-ast-derive",
605
605
  "serde",
@@ -610,13 +610,13 @@ dependencies = [
610
610
 
611
611
  [[package]]
612
612
  name = "polyglot-sql-ast-derive"
613
- version = "0.6.2"
613
+ version = "0.8.0"
614
614
  source = "registry+https://github.com/rust-lang/crates.io-index"
615
- checksum = "e3250a6ffcd1d39670eb532e2b1877ad430799c49cb91b243d63c9425b868161"
615
+ checksum = "c72cee7fdad5082a0cc73d7a9064914311fcd095b63bf5d85bd4c5b8dd89249e"
616
616
  dependencies = [
617
617
  "proc-macro2",
618
618
  "quote",
619
- "syn",
619
+ "syn 2.0.117",
620
620
  ]
621
621
 
622
622
  [[package]]
@@ -737,9 +737,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
737
737
 
738
738
  [[package]]
739
739
  name = "serde"
740
- version = "1.0.228"
740
+ version = "1.0.229"
741
741
  source = "registry+https://github.com/rust-lang/crates.io-index"
742
- checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
742
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
743
743
  dependencies = [
744
744
  "serde_core",
745
745
  "serde_derive",
@@ -766,29 +766,29 @@ dependencies = [
766
766
 
767
767
  [[package]]
768
768
  name = "serde_core"
769
- version = "1.0.228"
769
+ version = "1.0.229"
770
770
  source = "registry+https://github.com/rust-lang/crates.io-index"
771
- checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
771
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
772
772
  dependencies = [
773
773
  "serde_derive",
774
774
  ]
775
775
 
776
776
  [[package]]
777
777
  name = "serde_derive"
778
- version = "1.0.228"
778
+ version = "1.0.229"
779
779
  source = "registry+https://github.com/rust-lang/crates.io-index"
780
- checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
780
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
781
781
  dependencies = [
782
782
  "proc-macro2",
783
783
  "quote",
784
- "syn",
784
+ "syn 3.0.3",
785
785
  ]
786
786
 
787
787
  [[package]]
788
788
  name = "serde_json"
789
- version = "1.0.150"
789
+ version = "1.0.151"
790
790
  source = "registry+https://github.com/rust-lang/crates.io-index"
791
- checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
791
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
792
792
  dependencies = [
793
793
  "itoa",
794
794
  "memchr",
@@ -819,7 +819,7 @@ checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c"
819
819
  dependencies = [
820
820
  "proc-macro2",
821
821
  "quote",
822
- "syn",
822
+ "syn 2.0.117",
823
823
  ]
824
824
 
825
825
  [[package]]
@@ -857,6 +857,17 @@ dependencies = [
857
857
  "unicode-ident",
858
858
  ]
859
859
 
860
+ [[package]]
861
+ name = "syn"
862
+ version = "3.0.3"
863
+ source = "registry+https://github.com/rust-lang/crates.io-index"
864
+ checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
865
+ dependencies = [
866
+ "proc-macro2",
867
+ "quote",
868
+ "unicode-ident",
869
+ ]
870
+
860
871
  [[package]]
861
872
  name = "tempfile"
862
873
  version = "3.27.0"
@@ -881,11 +892,11 @@ dependencies = [
881
892
 
882
893
  [[package]]
883
894
  name = "thiserror"
884
- version = "2.0.18"
895
+ version = "2.0.19"
885
896
  source = "registry+https://github.com/rust-lang/crates.io-index"
886
- checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
897
+ checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
887
898
  dependencies = [
888
- "thiserror-impl 2.0.18",
899
+ "thiserror-impl 2.0.19",
889
900
  ]
890
901
 
891
902
  [[package]]
@@ -896,18 +907,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
896
907
  dependencies = [
897
908
  "proc-macro2",
898
909
  "quote",
899
- "syn",
910
+ "syn 2.0.117",
900
911
  ]
901
912
 
902
913
  [[package]]
903
914
  name = "thiserror-impl"
904
- version = "2.0.18"
915
+ version = "2.0.19"
905
916
  source = "registry+https://github.com/rust-lang/crates.io-index"
906
- checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
917
+ checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
907
918
  dependencies = [
908
919
  "proc-macro2",
909
920
  "quote",
910
- "syn",
921
+ "syn 3.0.3",
911
922
  ]
912
923
 
913
924
  [[package]]
@@ -991,7 +1002,7 @@ dependencies = [
991
1002
  "bumpalo",
992
1003
  "proc-macro2",
993
1004
  "quote",
994
- "syn",
1005
+ "syn 2.0.117",
995
1006
  "wasm-bindgen-shared",
996
1007
  ]
997
1008
 
@@ -1051,7 +1062,7 @@ checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89"
1051
1062
  dependencies = [
1052
1063
  "proc-macro2",
1053
1064
  "quote",
1054
- "syn",
1065
+ "syn 2.0.117",
1055
1066
  ]
1056
1067
 
1057
1068
  [[package]]
@@ -3,7 +3,7 @@ members = ["crates/*"]
3
3
  resolver = "3"
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.4-beta.1"
6
+ version = "0.2.4-rc.2"
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
- polyglot-sql = { version = "0.6.2", default-features = false, features = ["all-dialects", "semantic"] }
26
+ polyglot-sql = { version = "0.8.0", default-features = false, features = ["all-dialects", "semantic"] }
27
27
  path-slash = "0.2.1"
28
28
  clap = { version = "4", features = ["derive", "env"] }
29
29
  libc = "0.2"
@@ -34,7 +34,7 @@ insta = "1"
34
34
  serial_test = "3.4.0"
35
35
 
36
36
  # internal
37
- dlin-core = { version = "0.2.4-beta.1", path = "crates/dlin-core" }
37
+ dlin-core = { version = "0.2.4-rc.2", path = "crates/dlin-core" }
38
38
 
39
39
  [workspace.lints.rust]
40
40
  unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dlin-cli
3
- Version: 0.2.4b1
3
+ Version: 0.2.4rc2
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -5,6 +5,7 @@ use polyglot_sql::DialectType;
5
5
 
6
6
  use crate::parser::manifest::Manifest;
7
7
 
8
+ use super::manifest_schema::make_fq_table_name;
8
9
  use super::{
9
10
  ColumnLineageCache, ColumnLineageError, ColumnSource, ModelColumnLineage, TransformationType,
10
11
  find_model_by_name,
@@ -254,11 +255,3 @@ fn compute_single_column_lineage(
254
255
  .ok()
255
256
  .map(|r| (r.sources, r.transformation))
256
257
  }
257
-
258
- fn make_fq_table_name(database: Option<&str>, schema: Option<&str>, name: &str) -> String {
259
- match (database, schema) {
260
- (Some(db), Some(s)) => format!("{}.{}.{}", db, s, name),
261
- (None, Some(s)) => format!("{}.{}", s, name),
262
- _ => name.to_string(),
263
- }
264
- }
@@ -0,0 +1,302 @@
1
+ //! Manifest helpers that are safe to use for ordinal-aware analysis.
2
+ //!
3
+ //! The legacy YAML schema builders remain in `schema.rs`. The builder in this
4
+ //! module has a stricter contract: only a compiled query whose output order is
5
+ //! proven by polyglot-sql may become a `MappingSchema` relation.
6
+
7
+ use std::collections::HashSet;
8
+
9
+ use polyglot_sql::{DialectType, MappingSchema, Schema};
10
+
11
+ use crate::parser::cache::hash_str;
12
+ use crate::parser::manifest::{Manifest, ManifestNode};
13
+
14
+ use super::semantic_model::build_query_model_from_sql;
15
+
16
+ pub(super) fn make_fq_table_name(
17
+ database: Option<&str>,
18
+ schema: Option<&str>,
19
+ name: &str,
20
+ ) -> String {
21
+ match (database, schema) {
22
+ (Some(db), Some(s)) => format!("{}.{}.{}", db, s, name),
23
+ (None, Some(s)) => format!("{}.{}", s, name),
24
+ _ => name.to_string(),
25
+ }
26
+ }
27
+
28
+ /// Build a schema only from dependency models with a proven SQL output order.
29
+ ///
30
+ /// Manifest YAML columns are intentionally not consulted for the relation's
31
+ /// column order (or for adding a relation). A source, YAML-only model,
32
+ /// unnamed output, duplicate output name, or unresolved wildcard is omitted.
33
+ pub fn build_proven_ordered_schema(
34
+ manifest: &Manifest,
35
+ node: &ManifestNode,
36
+ dialect: DialectType,
37
+ ) -> Option<MappingSchema> {
38
+ let mut schema = MappingSchema::with_dialect(dialect);
39
+ let mut has_entries = false;
40
+
41
+ for dependency_id in &node.depends_on.nodes {
42
+ let Some(dependency) = manifest.nodes.get(dependency_id) else {
43
+ // Sources and other YAML-only relations do not prove an ordinal
44
+ // schema for this stage.
45
+ continue;
46
+ };
47
+ let Some(sql) = dependency.compiled_code.as_deref() else {
48
+ continue;
49
+ };
50
+ let Ok(query_model) = build_query_model_from_sql(sql, dialect, None) else {
51
+ continue;
52
+ };
53
+ let Some(column_names) = query_model.outputs.proven_ordered_named_outputs() else {
54
+ continue;
55
+ };
56
+
57
+ let columns = column_names
58
+ .into_iter()
59
+ .map(|name| (name, polyglot_sql::expressions::DataType::Unknown))
60
+ .collect::<Vec<_>>();
61
+ let qualified_name = make_fq_table_name(
62
+ dependency.database.as_deref(),
63
+ dependency.schema.as_deref(),
64
+ &dependency.name,
65
+ );
66
+ if schema.add_table(&qualified_name, &columns, None).is_ok() {
67
+ has_entries = true;
68
+ }
69
+ if qualified_name != dependency.name {
70
+ let _ = schema.add_table(&dependency.name, &columns, None);
71
+ }
72
+ }
73
+
74
+ has_entries.then_some(schema)
75
+ }
76
+
77
+ pub(super) fn compute_manifest_columns_hash(manifest: &Manifest, node: &ManifestNode) -> u64 {
78
+ let mut visited = HashSet::new();
79
+ hash_node_columns_transitive(manifest, node, &mut visited)
80
+ }
81
+
82
+ fn hash_node_columns_transitive(
83
+ manifest: &Manifest,
84
+ node: &ManifestNode,
85
+ visited: &mut HashSet<String>,
86
+ ) -> u64 {
87
+ let mut parts = Vec::new();
88
+
89
+ let mut own_cols = node.columns.keys().collect::<Vec<_>>();
90
+ own_cols.sort_unstable();
91
+ for column in own_cols {
92
+ parts.push(column.clone());
93
+ }
94
+ if let Some(code) = &node.compiled_code {
95
+ parts.push(format!("sql:{}", hash_str(code)));
96
+ }
97
+ parts.push("|".to_string());
98
+
99
+ let mut dependency_ids = node.depends_on.nodes.iter().collect::<Vec<_>>();
100
+ dependency_ids.sort_unstable();
101
+ for dependency_id in dependency_ids {
102
+ parts.push(dependency_id.clone());
103
+ if !visited.insert(dependency_id.clone()) {
104
+ continue;
105
+ }
106
+ if let Some(dependency) = manifest.nodes.get(dependency_id) {
107
+ let dependency_hash = hash_node_columns_transitive(manifest, dependency, visited);
108
+ parts.push(format!("node:{}", dependency_hash));
109
+ } else if let Some(source) = manifest.sources.get(dependency_id) {
110
+ let mut columns = source.columns.keys().collect::<Vec<_>>();
111
+ columns.sort_unstable();
112
+ for column in columns {
113
+ parts.push(column.clone());
114
+ }
115
+ if let Some(database) = &source.database {
116
+ parts.push(format!("db:{}", database));
117
+ }
118
+ if let Some(schema) = &source.schema {
119
+ parts.push(format!("schema:{}", schema));
120
+ }
121
+ if let Some(identifier) = &source.identifier {
122
+ parts.push(format!("id:{}", identifier));
123
+ }
124
+ }
125
+ }
126
+
127
+ hash_str(&parts.join("\0"))
128
+ }
129
+
130
+ #[cfg(test)]
131
+ mod tests {
132
+ use std::collections::HashMap;
133
+
134
+ use super::*;
135
+ use crate::parser::manifest::{DependsOn, ManifestColumn, ManifestConfig};
136
+
137
+ fn node(
138
+ unique_id: &str,
139
+ name: &str,
140
+ compiled_code: Option<&str>,
141
+ columns: &[&str],
142
+ dependencies: &[&str],
143
+ ) -> ManifestNode {
144
+ let columns = columns
145
+ .iter()
146
+ .map(|name| {
147
+ (
148
+ (*name).to_string(),
149
+ ManifestColumn {
150
+ name: (*name).to_string(),
151
+ },
152
+ )
153
+ })
154
+ .collect();
155
+ ManifestNode {
156
+ unique_id: unique_id.to_string(),
157
+ name: name.to_string(),
158
+ resource_type: "model".to_string(),
159
+ depends_on: DependsOn {
160
+ nodes: dependencies.iter().map(|id| (*id).to_string()).collect(),
161
+ },
162
+ config: ManifestConfig::default(),
163
+ description: None,
164
+ path: None,
165
+ original_file_path: None,
166
+ columns,
167
+ compiled_code: compiled_code.map(str::to_string),
168
+ database: None,
169
+ schema: None,
170
+ }
171
+ }
172
+
173
+ fn manifest(nodes: Vec<ManifestNode>) -> Manifest {
174
+ Manifest {
175
+ nodes: nodes
176
+ .into_iter()
177
+ .map(|node| (node.unique_id.clone(), node))
178
+ .collect::<HashMap<_, _>>(),
179
+ ..Manifest::default()
180
+ }
181
+ }
182
+
183
+ #[test]
184
+ fn yaml_map_order_does_not_change_proven_ordinal_schema() {
185
+ let upstream_id = "model.test.upstream";
186
+ let downstream_id = "model.test.downstream";
187
+ let upstream_sql = Some("SELECT first_col, second_col FROM source_table");
188
+ let downstream = node(
189
+ downstream_id,
190
+ "downstream",
191
+ Some("SELECT first_col FROM upstream"),
192
+ &[],
193
+ &[upstream_id],
194
+ );
195
+
196
+ let first = build_proven_ordered_schema(
197
+ &manifest(vec![
198
+ node(
199
+ upstream_id,
200
+ "upstream",
201
+ upstream_sql,
202
+ &["first_col", "second_col"],
203
+ &[],
204
+ ),
205
+ node(
206
+ downstream_id,
207
+ "downstream",
208
+ Some("SELECT first_col FROM upstream"),
209
+ &[],
210
+ &[upstream_id],
211
+ ),
212
+ ]),
213
+ &downstream,
214
+ DialectType::Generic,
215
+ )
216
+ .unwrap();
217
+ assert_eq!(
218
+ first.column_names("upstream").unwrap(),
219
+ vec!["first_col", "second_col"]
220
+ );
221
+ // The second manifest has the same SQL but a different YAML map order.
222
+ // Rebuild the node reference from that manifest so only the SQL proof
223
+ // participates in the schema.
224
+ let second_manifest = manifest(vec![
225
+ node(
226
+ upstream_id,
227
+ "upstream",
228
+ upstream_sql,
229
+ &["second_col", "first_col"],
230
+ &[],
231
+ ),
232
+ node(
233
+ downstream_id,
234
+ "downstream",
235
+ Some("SELECT first_col FROM upstream"),
236
+ &[],
237
+ &[upstream_id],
238
+ ),
239
+ ]);
240
+ let second = build_proven_ordered_schema(
241
+ &second_manifest,
242
+ second_manifest.nodes.get(downstream_id).unwrap(),
243
+ DialectType::Generic,
244
+ )
245
+ .unwrap();
246
+ assert_eq!(
247
+ second.column_names("upstream").unwrap(),
248
+ first.column_names("upstream").unwrap()
249
+ );
250
+ }
251
+
252
+ #[test]
253
+ fn only_proven_compiled_named_outputs_enter_the_schema() {
254
+ let good_id = "model.test.good";
255
+ let unnamed_id = "model.test.unnamed";
256
+ let star_id = "model.test.star";
257
+ let downstream = node(
258
+ "model.test.downstream",
259
+ "downstream",
260
+ Some("SELECT value FROM good"),
261
+ &[],
262
+ &[good_id, unnamed_id, star_id],
263
+ );
264
+ let manifest = manifest(vec![
265
+ node(
266
+ good_id,
267
+ "good",
268
+ Some("SELECT first_col, second_col FROM t"),
269
+ &[],
270
+ &[],
271
+ ),
272
+ node(
273
+ unnamed_id,
274
+ "unnamed",
275
+ Some("SELECT value * 2 FROM t"),
276
+ &["yaml_name"],
277
+ &[],
278
+ ),
279
+ node(
280
+ star_id,
281
+ "star",
282
+ Some("SELECT * FROM unknown"),
283
+ &["yaml_name"],
284
+ &[],
285
+ ),
286
+ downstream,
287
+ ]);
288
+
289
+ let schema = build_proven_ordered_schema(
290
+ &manifest,
291
+ manifest.nodes.get("model.test.downstream").unwrap(),
292
+ DialectType::Generic,
293
+ )
294
+ .unwrap();
295
+ assert_eq!(
296
+ schema.column_names("good").unwrap(),
297
+ vec!["first_col", "second_col"]
298
+ );
299
+ assert!(schema.column_names("unnamed").is_err());
300
+ assert!(schema.column_names("star").is_err());
301
+ }
302
+ }
@@ -1,7 +1,7 @@
1
1
  use std::collections::HashSet;
2
2
  use std::path::Path;
3
3
 
4
- use polyglot_sql::DialectType;
4
+ use polyglot_sql::{ColumnResolutionReason, DialectType, Error};
5
5
  use rayon::prelude::*;
6
6
 
7
7
  use crate::parser::manifest::Manifest;
@@ -9,8 +9,11 @@ use crate::parser::manifest::Manifest;
9
9
  mod cache;
10
10
  mod cross_model;
11
11
  mod impact;
12
+ pub mod manifest_schema;
12
13
  mod schema;
14
+ pub mod semantic_model;
13
15
  mod single_model;
16
+ mod star_guard;
14
17
  #[cfg(test)]
15
18
  mod tests;
16
19
  mod types;
@@ -23,8 +26,10 @@ pub use impact::{
23
26
  ColumnImpactReport, ImpactedColumn, compute_column_impact,
24
27
  compute_column_impact_with_manifest_path,
25
28
  };
26
- use schema::{build_yaml_schema_for_node, compute_manifest_columns_hash, infer_output_columns};
27
- use single_model::{has_unresolved_stars, prepare_lineage_context_with_expr, run_column_lineage};
29
+ use manifest_schema::compute_manifest_columns_hash;
30
+ use schema::{build_yaml_schema_for_node, infer_output_columns};
31
+ use single_model::{prepare_lineage_context_with_expr, run_column_lineage};
32
+ use star_guard::has_unresolved_stars;
28
33
  pub use types::{
29
34
  ColumnLineageEntry, ColumnLineageError, ColumnLineageErrorKind, ColumnSource,
30
35
  ModelColumnLineage, TransformationType,
@@ -174,14 +179,19 @@ pub fn compute_column_lineage_with_manifest_path(
174
179
  sources: result.sources,
175
180
  }),
176
181
  Err(e) => {
177
- let hint = (has_star_columns && e.contains("Cannot find column")).then(|| {
178
- "column may be introduced via SELECT * that could not be expanded; \
182
+ let hint =
183
+ (has_star_columns && is_indeterminate_column_resolution(&e)).then(|| {
184
+ "column may be introduced via SELECT * that could not be expanded; \
179
185
  define upstream columns in the model YAML to enable full resolution"
180
- .to_string()
181
- });
186
+ .to_string()
187
+ });
182
188
  Err(ColumnLineageError {
183
189
  kind: ColumnLineageErrorKind::ColumnNotFound,
184
- what: format!("column '{}': {}", col_name, e),
190
+ what: format!(
191
+ "column '{}': {}",
192
+ col_name,
193
+ single_model::format_lineage_error(&e)
194
+ ),
185
195
  why: None,
186
196
  hint,
187
197
  })
@@ -218,6 +228,16 @@ pub fn compute_column_lineage_with_manifest_path(
218
228
  result
219
229
  }
220
230
 
231
+ fn is_indeterminate_column_resolution(error: &Error) -> bool {
232
+ matches!(
233
+ error,
234
+ Error::ColumnResolution {
235
+ reason: ColumnResolutionReason::Indeterminate,
236
+ ..
237
+ }
238
+ )
239
+ }
240
+
221
241
  pub(super) fn find_model_by_name<'a>(
222
242
  manifest: &'a Manifest,
223
243
  name: &str,