dlin-cli 0.2.3__tar.gz → 0.2.4rc1__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 (135) hide show
  1. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/Cargo.lock +69 -46
  2. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/Cargo.toml +4 -4
  3. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/PKG-INFO +1 -1
  4. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/mod.rs +3 -1
  5. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/single_model.rs +85 -45
  6. dlin_cli-0.2.4rc1/crates/dlin-core/src/graph/column_lineage/star_guard.rs +652 -0
  7. dlin_cli-0.2.4rc1/crates/dlin-core/src/graph/column_lineage/tests/core_basic.rs +465 -0
  8. dlin_cli-0.2.4rc1/crates/dlin-core/src/graph/column_lineage/tests/core_cross_model.rs +293 -0
  9. dlin_cli-0.2.3/crates/dlin-core/src/graph/column_lineage/tests/core.rs → dlin_cli-0.2.4rc1/crates/dlin-core/src/graph/column_lineage/tests/core_star.rs +912 -924
  10. dlin_cli-0.2.4rc1/crates/dlin-core/src/graph/column_lineage/tests/core_util.rs +33 -0
  11. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/tests/mod.rs +4 -1
  12. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/LICENSE +0 -0
  13. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/README.md +0 -0
  14. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/Cargo.toml +0 -0
  15. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/README.md +0 -0
  16. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/src/cli.rs +0 -0
  17. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/src/main.rs +0 -0
  18. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/src/mcp.rs +0 -0
  19. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin/tests/integration_test.rs +0 -0
  20. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/Cargo.toml +0 -0
  21. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/README.md +0 -0
  22. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/error.rs +0 -0
  23. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/mod.rs +0 -0
  24. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/tests/build_graph.rs +0 -0
  25. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/tests/generic_tests.rs +0 -0
  26. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/tests/mod.rs +0 -0
  27. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/tests/ref_parsing.rs +0 -0
  28. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/builder/tests/versioned.rs +0 -0
  29. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/cache.rs +0 -0
  30. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/cross_model.rs +0 -0
  31. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/impact.rs +0 -0
  32. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/schema.rs +0 -0
  33. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/tests/cache.rs +0 -0
  34. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/tests/impact.rs +0 -0
  35. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/column_lineage/types.rs +0 -0
  36. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/mod.rs +0 -0
  37. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/collapse.rs +0 -0
  38. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/filter_graph.rs +0 -0
  39. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/mod.rs +0 -0
  40. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/output.rs +0 -0
  41. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/search.rs +0 -0
  42. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/selector.rs +0 -0
  43. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot.snap +0 -0
  44. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_bfs_pseudoendpoint.snap +0 -0
  45. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_fan_out.snap +0 -0
  46. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_leaf_model.snap +0 -0
  47. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_multiple_focus_models.snap +0 -0
  48. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_no_source_exposure.snap +0 -0
  49. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_preserve_focus.snap +0 -0
  50. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_node_type_filter.snap +0 -0
  51. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_filter.snap +0 -0
  52. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_with_node_type.snap +0 -0
  53. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/transitive.rs +0 -0
  54. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/filter/tests/versioned.rs +0 -0
  55. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/impact.rs +0 -0
  56. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/mod.rs +0 -0
  57. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/graph/types.rs +0 -0
  58. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/input.rs +0 -0
  59. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/lib.rs +0 -0
  60. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/cache.rs +0 -0
  61. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/columns.rs +0 -0
  62. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/discovery.rs +0 -0
  63. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/jinja.rs +0 -0
  64. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/manifest.rs +0 -0
  65. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/manifest_cache.rs +0 -0
  66. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/mod.rs +0 -0
  67. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/project.rs +0 -0
  68. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/sql.rs +0 -0
  69. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/parser/yaml_schema.rs +0 -0
  70. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/ascii.rs +0 -0
  71. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/column_graph.rs +0 -0
  72. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/dot.rs +0 -0
  73. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/html.rs +0 -0
  74. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/impact.rs +0 -0
  75. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/json.rs +0 -0
  76. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/layout.rs +0 -0
  77. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/list.rs +0 -0
  78. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/mermaid.rs +0 -0
  79. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/mod.rs +0 -0
  80. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/plain.rs +0 -0
  81. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_all_transformation_types.snap +0 -0
  82. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_escapes_special_chars.snap +0 -0
  83. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_id_collision_avoided.snap +0 -0
  84. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_indirect.snap +0 -0
  85. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_single.snap +0 -0
  86. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_single_model.snap +0 -0
  87. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_via_path.snap +0 -0
  88. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid.snap +0 -0
  89. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid_indirect_edge_label.snap +0 -0
  90. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain.snap +0 -0
  91. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_multi_hop.snap +0 -0
  92. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_non_direct_intermediate.snap +0 -0
  93. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_dotted_table_name.snap +0 -0
  94. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_id_collision_avoided.snap +0 -0
  95. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_label_escaping.snap +0 -0
  96. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_single_model.snap +0 -0
  97. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_model_path_non_direct_annotation.snap +0 -0
  98. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_no_sources.snap +0 -0
  99. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_single_model.snap +0 -0
  100. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__group_by_node_type.snap +0 -0
  101. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_all_edge_types.snap +0 -0
  102. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb.snap +0 -0
  103. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
  104. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_group_by_directory.snap +0 -0
  105. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_lineage.snap +0 -0
  106. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_transitive_edges.snap +0 -0
  107. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__html__tests__snapshot_html_json.snap +0 -0
  108. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json.snap +0 -0
  109. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
  110. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text.snap +0 -0
  111. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
  112. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_json_with_sql.snap +0 -0
  113. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_lineage.snap +0 -0
  114. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_node_metadata.snap +0 -0
  115. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_json.snap +0 -0
  116. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_plain.snap +0 -0
  117. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__group_by_node_type.snap +0 -0
  118. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
  119. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
  120. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_lineage.snap +0 -0
  121. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_single_model.snap +0 -0
  122. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
  123. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
  124. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
  125. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
  126. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
  127. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_lineage.snap +0 -0
  128. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
  129. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__plain__tests__snapshot_plain.snap +0 -0
  130. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_json.snap +0 -0
  131. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_text.snap +0 -0
  132. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/summary.rs +0 -0
  133. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/src/render/svg.rs +0 -0
  134. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/crates/dlin-core/tests/column_lineage_test.rs +0 -0
  135. {dlin_cli-0.2.3 → dlin_cli-0.2.4rc1}/pyproject.toml +0 -0
@@ -87,9 +87,9 @@ dependencies = [
87
87
 
88
88
  [[package]]
89
89
  name = "anyhow"
90
- version = "1.0.102"
90
+ version = "1.0.104"
91
91
  source = "registry+https://github.com/rust-lang/crates.io-index"
92
- checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
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.3"
233
+ version = "0.2.4-rc.1"
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.3"
250
+ version = "0.2.4-rc.1"
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",
@@ -398,9 +398,9 @@ dependencies = [
398
398
 
399
399
  [[package]]
400
400
  name = "granit-parser"
401
- version = "0.0.3"
401
+ version = "0.0.7"
402
402
  source = "registry+https://github.com/rust-lang/crates.io-index"
403
- checksum = "f50ba32164f9e098d5da618776a32afbb32270adcbe3d3d006107dae11e37c91"
403
+ checksum = "d03f81ad4732830d85cfd417a9f62cde6dadda4354d37d078a6084a19560aa2d"
404
404
  dependencies = [
405
405
  "arraydeque",
406
406
  "smallvec",
@@ -439,9 +439,9 @@ dependencies = [
439
439
 
440
440
  [[package]]
441
441
  name = "insta"
442
- version = "1.47.2"
442
+ version = "1.48.0"
443
443
  source = "registry+https://github.com/rust-lang/crates.io-index"
444
- checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e"
444
+ checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82"
445
445
  dependencies = [
446
446
  "console",
447
447
  "once_cell",
@@ -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"
@@ -512,9 +512,9 @@ checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
512
512
 
513
513
  [[package]]
514
514
  name = "minijinja"
515
- version = "2.20.0"
515
+ version = "2.21.0"
516
516
  source = "registry+https://github.com/rust-lang/crates.io-index"
517
- checksum = "2929e494b2280e1e18959bb2e121da03347ae896896fdfaceaab43c88a02803f"
517
+ checksum = "cb3d648e68cea56d9858d535ee28f9538404e2dd8cb08ed0bd05dca379477f39"
518
518
  dependencies = [
519
519
  "memo-map",
520
520
  "serde",
@@ -597,16 +597,28 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
597
597
 
598
598
  [[package]]
599
599
  name = "polyglot-sql"
600
- version = "0.4.4"
600
+ version = "0.6.3"
601
601
  source = "registry+https://github.com/rust-lang/crates.io-index"
602
- checksum = "b0d5ea9283f03d3b6c32a230e60e7c6bc854e5bec83c399c75cad02bf46e9622"
602
+ checksum = "b54acea84522c6c51f6cbfa56600097cd8c6c5583a70e67f2787b6f70c3dd956"
603
603
  dependencies = [
604
+ "polyglot-sql-ast-derive",
604
605
  "serde",
605
606
  "serde_json",
606
607
  "thiserror 1.0.69",
607
608
  "unicode-segmentation",
608
609
  ]
609
610
 
611
+ [[package]]
612
+ name = "polyglot-sql-ast-derive"
613
+ version = "0.6.3"
614
+ source = "registry+https://github.com/rust-lang/crates.io-index"
615
+ checksum = "c19af779599f7bf0ec303044dbb8e1c3f6c5b4dca29ea703b033519860104031"
616
+ dependencies = [
617
+ "proc-macro2",
618
+ "quote",
619
+ "syn 2.0.117",
620
+ ]
621
+
610
622
  [[package]]
611
623
  name = "proc-macro2"
612
624
  version = "1.0.106"
@@ -725,9 +737,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
725
737
 
726
738
  [[package]]
727
739
  name = "serde"
728
- version = "1.0.228"
740
+ version = "1.0.229"
729
741
  source = "registry+https://github.com/rust-lang/crates.io-index"
730
- checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
742
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
731
743
  dependencies = [
732
744
  "serde_core",
733
745
  "serde_derive",
@@ -735,9 +747,9 @@ dependencies = [
735
747
 
736
748
  [[package]]
737
749
  name = "serde-saphyr"
738
- version = "0.0.27"
750
+ version = "0.0.29"
739
751
  source = "registry+https://github.com/rust-lang/crates.io-index"
740
- checksum = "5897b4c3faadadd35fdb6689f015641f3bc481d5adaaac56231ea15aeb243db3"
752
+ checksum = "7bd22781911de0ca6debda95f073c8f18bec65d1a94f1fa9573f3102e514cea4"
741
753
  dependencies = [
742
754
  "ahash",
743
755
  "annotate-snippets",
@@ -747,36 +759,36 @@ dependencies = [
747
759
  "granit-parser",
748
760
  "nohash-hasher",
749
761
  "num-traits",
750
- "serde",
762
+ "serde_core",
751
763
  "smallvec",
752
764
  "zmij",
753
765
  ]
754
766
 
755
767
  [[package]]
756
768
  name = "serde_core"
757
- version = "1.0.228"
769
+ version = "1.0.229"
758
770
  source = "registry+https://github.com/rust-lang/crates.io-index"
759
- checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
771
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
760
772
  dependencies = [
761
773
  "serde_derive",
762
774
  ]
763
775
 
764
776
  [[package]]
765
777
  name = "serde_derive"
766
- version = "1.0.228"
778
+ version = "1.0.229"
767
779
  source = "registry+https://github.com/rust-lang/crates.io-index"
768
- checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
780
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
769
781
  dependencies = [
770
782
  "proc-macro2",
771
783
  "quote",
772
- "syn",
784
+ "syn 3.0.3",
773
785
  ]
774
786
 
775
787
  [[package]]
776
788
  name = "serde_json"
777
- version = "1.0.150"
789
+ version = "1.0.151"
778
790
  source = "registry+https://github.com/rust-lang/crates.io-index"
779
- checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
791
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
780
792
  dependencies = [
781
793
  "itoa",
782
794
  "memchr",
@@ -807,7 +819,7 @@ checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c"
807
819
  dependencies = [
808
820
  "proc-macro2",
809
821
  "quote",
810
- "syn",
822
+ "syn 2.0.117",
811
823
  ]
812
824
 
813
825
  [[package]]
@@ -845,6 +857,17 @@ dependencies = [
845
857
  "unicode-ident",
846
858
  ]
847
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
+
848
871
  [[package]]
849
872
  name = "tempfile"
850
873
  version = "3.27.0"
@@ -869,11 +892,11 @@ dependencies = [
869
892
 
870
893
  [[package]]
871
894
  name = "thiserror"
872
- version = "2.0.18"
895
+ version = "2.0.19"
873
896
  source = "registry+https://github.com/rust-lang/crates.io-index"
874
- checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
897
+ checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
875
898
  dependencies = [
876
- "thiserror-impl 2.0.18",
899
+ "thiserror-impl 2.0.19",
877
900
  ]
878
901
 
879
902
  [[package]]
@@ -884,18 +907,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
884
907
  dependencies = [
885
908
  "proc-macro2",
886
909
  "quote",
887
- "syn",
910
+ "syn 2.0.117",
888
911
  ]
889
912
 
890
913
  [[package]]
891
914
  name = "thiserror-impl"
892
- version = "2.0.18"
915
+ version = "2.0.19"
893
916
  source = "registry+https://github.com/rust-lang/crates.io-index"
894
- checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
917
+ checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
895
918
  dependencies = [
896
919
  "proc-macro2",
897
920
  "quote",
898
- "syn",
921
+ "syn 3.0.3",
899
922
  ]
900
923
 
901
924
  [[package]]
@@ -979,7 +1002,7 @@ dependencies = [
979
1002
  "bumpalo",
980
1003
  "proc-macro2",
981
1004
  "quote",
982
- "syn",
1005
+ "syn 2.0.117",
983
1006
  "wasm-bindgen-shared",
984
1007
  ]
985
1008
 
@@ -1039,7 +1062,7 @@ checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89"
1039
1062
  dependencies = [
1040
1063
  "proc-macro2",
1041
1064
  "quote",
1042
- "syn",
1065
+ "syn 2.0.117",
1043
1066
  ]
1044
1067
 
1045
1068
  [[package]]
@@ -3,7 +3,7 @@ members = ["crates/*"]
3
3
  resolver = "3"
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.3"
6
+ version = "0.2.4-rc.1"
7
7
  edition = "2024"
8
8
  license = "MIT"
9
9
  repository = "https://github.com/eitsupi/dlin"
@@ -13,7 +13,7 @@ homepage = "https://github.com/eitsupi/dlin"
13
13
  petgraph = { version = "0.8", features = ["serde-1"] }
14
14
  serde = { version = "1", features = ["derive"] }
15
15
  serde_json = "1"
16
- serde-saphyr = "0.0.27"
16
+ serde-saphyr = "0.0.29"
17
17
  regex = "1"
18
18
  walkdir = "2"
19
19
  colored = "3"
@@ -23,7 +23,7 @@ indexmap = "2"
23
23
  minijinja = "2"
24
24
  rayon = "1"
25
25
  globset = "0.4"
26
- polyglot-sql = { version = "0.4.4", default-features = false, features = ["all-dialects", "semantic"] }
26
+ polyglot-sql = { version = "0.6.3", 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.3", path = "crates/dlin-core" }
37
+ dlin-core = { version = "0.2.4-rc.1", 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.3
3
+ Version: 0.2.4rc1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -11,6 +11,7 @@ mod cross_model;
11
11
  mod impact;
12
12
  mod schema;
13
13
  mod single_model;
14
+ mod star_guard;
14
15
  #[cfg(test)]
15
16
  mod tests;
16
17
  mod types;
@@ -24,7 +25,8 @@ pub use impact::{
24
25
  compute_column_impact_with_manifest_path,
25
26
  };
26
27
  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};
28
+ use single_model::{prepare_lineage_context_with_expr, run_column_lineage};
29
+ use star_guard::has_unresolved_stars;
28
30
  pub use types::{
29
31
  ColumnLineageEntry, ColumnLineageError, ColumnLineageErrorKind, ColumnSource,
30
32
  ModelColumnLineage, TransformationType,
@@ -1,14 +1,18 @@
1
+ use polyglot_sql::lineage::LineageNode;
2
+ use polyglot_sql::scope::SourceKind;
1
3
  use polyglot_sql::{DialectType, Expression};
2
4
 
3
5
  use crate::parser::manifest::Manifest;
4
6
 
5
7
  use super::schema::build_schema_from_manifest;
8
+ use super::star_guard::StarGuard;
6
9
  use super::{ColumnSource, TransformationType};
7
10
 
8
11
  pub(super) struct LineageContext {
9
12
  pub(super) expanded_expr: Expression,
10
13
  schema: Option<polyglot_sql::MappingSchema>,
11
14
  dialect: DialectType,
15
+ star_guard: StarGuard,
12
16
  }
13
17
 
14
18
  pub(super) fn prepare_lineage_context(
@@ -31,7 +35,6 @@ pub(super) fn prepare_lineage_context_with_expr(
31
35
  Some(e) => e.clone(),
32
36
  None => polyglot_sql::parse_one(compiled_code, dialect).map_err(|e| format!("{}", e))?,
33
37
  };
34
-
35
38
  let schema = build_schema_from_manifest(manifest, node, dialect);
36
39
 
37
40
  let mut expanded_expr = expr;
@@ -39,11 +42,12 @@ pub(super) fn prepare_lineage_context_with_expr(
39
42
  &mut expanded_expr,
40
43
  schema.as_ref().map(|s| s as &dyn polyglot_sql::Schema),
41
44
  );
42
-
45
+ let star_guard = StarGuard::new(&expanded_expr, Some(dialect));
43
46
  Ok(LineageContext {
44
47
  expanded_expr,
45
48
  schema,
46
49
  dialect,
50
+ star_guard,
47
51
  })
48
52
  }
49
53
 
@@ -51,54 +55,91 @@ pub(super) fn run_column_lineage(
51
55
  col_name: &str,
52
56
  ctx: &LineageContext,
53
57
  ) -> Result<ColumnLineageResult, String> {
58
+ let modifier_expr =
59
+ ctx.star_guard
60
+ .materialize_star_modifier(&ctx.expanded_expr, col_name, ctx.dialect);
61
+ let lineage_expr = modifier_expr.as_ref().unwrap_or(&ctx.expanded_expr);
62
+ let lineage_result = lineage_node(col_name, lineage_expr, ctx);
63
+
64
+ match lineage_result {
65
+ Ok(node) => {
66
+ if ctx.star_guard.rejects(&node) {
67
+ Err(format!("Cannot find column '{}' in query", col_name))
68
+ } else {
69
+ Ok(extract_leaf_sources(&node))
70
+ }
71
+ }
72
+ Err(e) => explicit_set_operand_lineage(col_name, lineage_expr, ctx, &e)
73
+ .ok_or_else(|| format_lineage_error(&e)),
74
+ }
75
+ }
76
+
77
+ fn lineage_node(
78
+ col_name: &str,
79
+ expr: &Expression,
80
+ ctx: &LineageContext,
81
+ ) -> Result<LineageNode, polyglot_sql::Error> {
54
82
  let dialect = Some(ctx.dialect);
55
- let lineage_result = if let Some(ref s) = ctx.schema {
83
+ if let Some(ref schema) = ctx.schema {
56
84
  polyglot_sql::lineage::lineage_with_schema(
57
85
  col_name,
58
- &ctx.expanded_expr,
59
- Some(s as &dyn polyglot_sql::Schema),
86
+ expr,
87
+ Some(schema as &dyn polyglot_sql::Schema),
60
88
  dialect,
61
89
  false,
62
90
  )
63
- .or_else(|_| polyglot_sql::lineage::lineage(col_name, &ctx.expanded_expr, dialect, false))
91
+ .or_else(|_| polyglot_sql::lineage::lineage(col_name, expr, dialect, false))
64
92
  } else {
65
- polyglot_sql::lineage::lineage(col_name, &ctx.expanded_expr, dialect, false)
66
- };
93
+ polyglot_sql::lineage::lineage(col_name, expr, dialect, false)
94
+ }
95
+ }
67
96
 
68
- match lineage_result {
69
- Ok(node) => Ok(extract_leaf_sources(&node)),
70
- Err(e) => Err(format_lineage_error(&e)),
97
+ // TODO: this locates an operand's projection by ordinal (see
98
+ // `StarGuard::explicit_set_operands`) but then re-derives lineage by looking that
99
+ // projection's output *name* back up via `lineage_node`, instead of tracing the
100
+ // already-located projection directly. Unaliased expressions have no name to look
101
+ // up (e.g. `fee * 2` in `SELECT other.*, fee FROM a UNION ALL SELECT x, fee * 2
102
+ // FROM b`) and are silently dropped; duplicate output names (`SELECT a.id, b.id`)
103
+ // make the lookup ambiguous and can retrace the wrong projection. Redesign: keep
104
+ // projection-list position and output ordinal as distinct types and trace
105
+ // positionally instead of round-tripping through a name.
106
+ fn explicit_set_operand_lineage(
107
+ col_name: &str,
108
+ expr: &Expression,
109
+ ctx: &LineageContext,
110
+ original_error: &polyglot_sql::Error,
111
+ ) -> Option<ColumnLineageResult> {
112
+ let error = original_error.to_string();
113
+ if !error.contains("Cannot find column") || !error.contains("in set operation") {
114
+ return None;
71
115
  }
116
+
117
+ // A set's leftmost star can make its output names unknowable to polyglot-sql.
118
+ // Trace only intact operands that explicitly project the requested ordinal;
119
+ // unresolved star operands contribute no source instead of a guessed one.
120
+ let operands = StarGuard::explicit_set_operands(expr, col_name, Some(ctx.dialect))?;
121
+ let mut results = operands.into_iter().filter_map(|(operand, operand_name)| {
122
+ let node = lineage_node(operand_name, operand, ctx).ok()?;
123
+ (!ctx.star_guard.rejects(&node)).then(|| extract_leaf_sources(&node))
124
+ });
125
+ let first = results.next()?;
126
+ Some(results.fold(first, merge_lineage_results))
72
127
  }
73
128
 
74
- pub(super) fn has_unresolved_stars(expr: &Expression) -> bool {
75
- match expr {
76
- Expression::Select(select) => {
77
- let outer_has_star = select.expressions.iter().any(|e| {
78
- matches!(e, Expression::Star(_))
79
- || matches!(e, Expression::Column(c) if c.name.name == "*")
80
- });
81
- if outer_has_star {
82
- return true;
83
- }
84
- if let Some(with) = &select.with
85
- && with.ctes.iter().any(|cte| has_unresolved_stars(&cte.this))
86
- {
87
- return true;
88
- }
89
- if let Some(from) = &select.from
90
- && from.expressions.iter().any(has_unresolved_stars)
91
- {
92
- return true;
93
- }
94
- if select.joins.iter().any(|j| has_unresolved_stars(&j.this)) {
95
- return true;
96
- }
97
- false
98
- }
99
- Expression::Subquery(subq) => has_unresolved_stars(&subq.this),
100
- _ => false,
129
+ fn merge_lineage_results(
130
+ mut left: ColumnLineageResult,
131
+ right: ColumnLineageResult,
132
+ ) -> ColumnLineageResult {
133
+ if left.transformation == TransformationType::Direct
134
+ && right.transformation != TransformationType::Direct
135
+ {
136
+ left.transformation = right.transformation;
101
137
  }
138
+ left.sources.extend(right.sources);
139
+ left.sources
140
+ .sort_by(|a, b| (&a.table, &a.column).cmp(&(&b.table, &b.column)));
141
+ left.sources.dedup();
142
+ left
102
143
  }
103
144
 
104
145
  pub(super) fn format_lineage_error(e: &polyglot_sql::Error) -> String {
@@ -118,7 +159,7 @@ pub(super) fn format_lineage_error(e: &polyglot_sql::Error) -> String {
118
159
  }
119
160
  }
120
161
 
121
- fn classify_transformation(node: &polyglot_sql::lineage::LineageNode) -> TransformationType {
162
+ fn classify_transformation(node: &LineageNode) -> TransformationType {
122
163
  let t = classify_expression(&node.expression);
123
164
  if t != TransformationType::Direct || node.downstream.is_empty() {
124
165
  return t;
@@ -135,8 +176,7 @@ fn classify_transformation(node: &polyglot_sql::lineage::LineageNode) -> Transfo
135
176
  TransformationType::Direct
136
177
  }
137
178
 
138
- fn classify_expression(expr: &polyglot_sql::Expression) -> TransformationType {
139
- use polyglot_sql::Expression;
179
+ fn classify_expression(expr: &Expression) -> TransformationType {
140
180
  match expr {
141
181
  Expression::Column(_) | Expression::Identifier(_) => TransformationType::Direct,
142
182
  Expression::Alias(alias) => classify_expression(&alias.this),
@@ -169,7 +209,7 @@ pub(super) struct ColumnLineageResult {
169
209
  pub(super) transformation: TransformationType,
170
210
  }
171
211
 
172
- fn extract_leaf_sources(node: &polyglot_sql::lineage::LineageNode) -> ColumnLineageResult {
212
+ fn extract_leaf_sources(node: &LineageNode) -> ColumnLineageResult {
173
213
  let transformation = classify_transformation(node);
174
214
  let mut sources = Vec::new();
175
215
  collect_leaves(node, &mut sources);
@@ -181,9 +221,9 @@ fn extract_leaf_sources(node: &polyglot_sql::lineage::LineageNode) -> ColumnLine
181
221
  }
182
222
  }
183
223
 
184
- fn collect_leaves(node: &polyglot_sql::lineage::LineageNode, sources: &mut Vec<ColumnSource>) {
224
+ fn collect_leaves(node: &LineageNode, sources: &mut Vec<ColumnSource>) {
185
225
  if node.downstream.is_empty() {
186
- if node.source_kind == polyglot_sql::scope::SourceKind::Virtual {
226
+ if node.source_kind == SourceKind::Virtual {
187
227
  return;
188
228
  }
189
229
  let name = &node.name;
@@ -204,7 +244,7 @@ fn collect_leaves(node: &polyglot_sql::lineage::LineageNode, sources: &mut Vec<C
204
244
  });
205
245
  } else {
206
246
  sources.push(ColumnSource {
207
- table: String::new(),
247
+ table: node.source_name.clone(),
208
248
  column: name.to_string(),
209
249
  model_path: vec![],
210
250
  });