sql-glider 0.1.5__tar.gz → 0.1.6__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 (137) hide show
  1. {sql_glider-0.1.5 → sql_glider-0.1.6}/PKG-INFO +1 -1
  2. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2026-01-26-file-scoped-schema-context.md +4 -2
  3. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/_version.py +2 -2
  4. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/lineage/analyzer.py +6 -0
  5. sql_glider-0.1.6/tests/fixtures/original_queries/test_cte_view_star.sql +22 -0
  6. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/lineage/test_analyzer.py +54 -0
  7. {sql_glider-0.1.5 → sql_glider-0.1.6}/.github/workflows/ci.yml +0 -0
  8. {sql_glider-0.1.5 → sql_glider-0.1.6}/.github/workflows/publish.yml +0 -0
  9. {sql_glider-0.1.5 → sql_glider-0.1.6}/.gitignore +0 -0
  10. {sql_glider-0.1.5 → sql_glider-0.1.6}/.python-version +0 -0
  11. {sql_glider-0.1.5 → sql_glider-0.1.6}/ARCHITECTURE.md +0 -0
  12. {sql_glider-0.1.5 → sql_glider-0.1.6}/CLAUDE.md +0 -0
  13. {sql_glider-0.1.5 → sql_glider-0.1.6}/LICENSE +0 -0
  14. {sql_glider-0.1.5 → sql_glider-0.1.6}/README.md +0 -0
  15. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-05-column-level-lineage.md +0 -0
  16. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-05-reverse-lineage.md +0 -0
  17. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-06-config-file-support.md +0 -0
  18. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-06-graph-lineage.md +0 -0
  19. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-06-unify-single-multi-query.md +0 -0
  20. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-07-sample-data-model.md +0 -0
  21. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-07-sql-templating.md +0 -0
  22. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-08-tables-command.md +0 -0
  23. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-09-graph-query-paths.md +0 -0
  24. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-13-dissect-command.md +0 -0
  25. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2025-12-14-tables-pull-command.md +0 -0
  26. {sql_glider-0.1.5 → sql_glider-0.1.6}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
  27. {sql_glider-0.1.5 → sql_glider-0.1.6}/pyproject.toml +0 -0
  28. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/README.md +0 -0
  29. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/expire_dim_customer.sql +0 -0
  30. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/load_fact_orders.sql +0 -0
  31. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/load_fact_payments.sql +0 -0
  32. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/merge_dim_customer.sql +0 -0
  33. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/merge_dim_product.sql +0 -0
  34. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
  35. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/complex/conditional_merge.sql +0 -0
  36. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/complex/cte_insert.sql +0 -0
  37. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/complex/multi_table_transform.sql +0 -0
  38. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/dim_customer.sql +0 -0
  39. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/dim_product.sql +0 -0
  40. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/fact_orders.sql +0 -0
  41. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/fact_payments.sql +0 -0
  42. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_addresses.sql +0 -0
  43. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_customers.sql +0 -0
  44. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_order_items.sql +0 -0
  45. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_orders.sql +0 -0
  46. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_payments.sql +0 -0
  47. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/raw_products.sql +0 -0
  48. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/stg_customers.sql +0 -0
  49. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/stg_orders.sql +0 -0
  50. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/stg_payments.sql +0 -0
  51. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/ddl/stg_products.sql +0 -0
  52. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
  53. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
  54. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
  55. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
  56. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/maintenance/update_product_status.sql +0 -0
  57. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
  58. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
  59. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
  60. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
  61. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/staging/load_stg_customers.sql +0 -0
  62. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/staging/load_stg_orders.sql +0 -0
  63. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/staging/load_stg_payments.sql +0 -0
  64. {sql_glider-0.1.5 → sql_glider-0.1.6}/sample_data_model/staging/load_stg_products.sql +0 -0
  65. {sql_glider-0.1.5 → sql_glider-0.1.6}/sqlglider.toml.example +0 -0
  66. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/__init__.py +0 -0
  67. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/catalog/__init__.py +0 -0
  68. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/catalog/base.py +0 -0
  69. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/catalog/databricks.py +0 -0
  70. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/catalog/registry.py +0 -0
  71. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/cli.py +0 -0
  72. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/dissection/__init__.py +0 -0
  73. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/dissection/analyzer.py +0 -0
  74. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/dissection/formatters.py +0 -0
  75. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/dissection/models.py +0 -0
  76. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/global_models.py +0 -0
  77. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/__init__.py +0 -0
  78. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/builder.py +0 -0
  79. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/merge.py +0 -0
  80. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/models.py +0 -0
  81. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/query.py +0 -0
  82. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/graph/serialization.py +0 -0
  83. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/lineage/__init__.py +0 -0
  84. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/lineage/formatters.py +0 -0
  85. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/templating/__init__.py +0 -0
  86. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/templating/base.py +0 -0
  87. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/templating/jinja.py +0 -0
  88. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/templating/registry.py +0 -0
  89. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/templating/variables.py +0 -0
  90. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/utils/__init__.py +0 -0
  91. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/utils/config.py +0 -0
  92. {sql_glider-0.1.5 → sql_glider-0.1.6}/src/sqlglider/utils/file_utils.py +0 -0
  93. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/__init__.py +0 -0
  94. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
  95. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
  96. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/customers.sql +0 -0
  97. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/orders.sql +0 -0
  98. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/reports.sql +0 -0
  99. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
  100. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_cte.sql +0 -0
  101. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
  102. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
  103. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_multi.sql +0 -0
  104. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
  105. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_single_query.sql +0 -0
  106. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_subquery.sql +0 -0
  107. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_tables.sql +0 -0
  108. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_view.sql +0 -0
  109. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
  110. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/fixtures/sample_manifest.csv +0 -0
  111. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/__init__.py +0 -0
  112. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/catalog/__init__.py +0 -0
  113. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/catalog/test_base.py +0 -0
  114. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/catalog/test_databricks.py +0 -0
  115. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/catalog/test_registry.py +0 -0
  116. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/dissection/__init__.py +0 -0
  117. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/dissection/test_analyzer.py +0 -0
  118. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/dissection/test_formatters.py +0 -0
  119. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/dissection/test_models.py +0 -0
  120. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/__init__.py +0 -0
  121. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/test_builder.py +0 -0
  122. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/test_merge.py +0 -0
  123. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/test_models.py +0 -0
  124. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/test_query.py +0 -0
  125. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/graph/test_serialization.py +0 -0
  126. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/lineage/__init__.py +0 -0
  127. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/lineage/test_formatters.py +0 -0
  128. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/templating/__init__.py +0 -0
  129. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/templating/test_base.py +0 -0
  130. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/templating/test_jinja.py +0 -0
  131. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/templating/test_registry.py +0 -0
  132. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/templating/test_variables.py +0 -0
  133. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/test_cli.py +0 -0
  134. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/utils/__init__.py +0 -0
  135. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/utils/test_config.py +0 -0
  136. {sql_glider-0.1.5 → sql_glider-0.1.6}/tests/sqlglider/utils/test_file_utils.py +0 -0
  137. {sql_glider-0.1.5 → sql_glider-0.1.6}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-glider
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
5
5
  Project-URL: Homepage, https://github.com/rycowhi/sql-glider/
6
6
  Project-URL: Repository, https://github.com/rycowhi/sql-glider/
@@ -96,6 +96,8 @@ node = lineage(
96
96
  | LATERAL VIEW posexplode | Collects both position and element columns |
97
97
  | Multiple LATERAL VIEWs | Collects columns from all LATERAL VIEWs |
98
98
  | LATERAL VIEW OUTER | Same handling as regular LATERAL VIEW |
99
+ | LEFT SEMI JOIN | Only includes left table columns (right table excluded) |
100
+ | LEFT ANTI JOIN | Only includes left table columns (right table excluded) |
99
101
 
100
102
  ---
101
103
 
@@ -103,8 +105,8 @@ node = lineage(
103
105
 
104
106
  | File | Changes |
105
107
  |------|---------|
106
- | `src/sqlglider/lineage/analyzer.py` | Added `_file_schema` instance variable; Added 9 schema extraction methods (including `_resolve_lateral_columns`); Modified `analyze_queries()` and `_analyze_column_lineage_internal()` and `get_output_columns()` |
107
- | `tests/sqlglider/lineage/test_analyzer.py` | Added `TestFileSchemaExtraction` (9 tests), `TestCrossStatementLineage` (12 tests), and `TestLateralViewColumnResolution` (5 tests) |
108
+ | `src/sqlglider/lineage/analyzer.py` | Added `_file_schema` instance variable; Added 9 schema extraction methods (including `_resolve_lateral_columns`); Modified `analyze_queries()` and `_analyze_column_lineage_internal()` and `get_output_columns()`; Added SEMI/ANTI join handling in `_resolve_star_columns()` |
109
+ | `tests/sqlglider/lineage/test_analyzer.py` | Added `TestFileSchemaExtraction` (9 tests), `TestCrossStatementLineage` (12 tests), `TestLateralViewColumnResolution` (5 tests), and `TestSemiAntiJoinColumnResolution` (3 tests) |
108
110
 
109
111
  ---
110
112
 
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.5'
32
- __version_tuple__ = version_tuple = (0, 1, 5)
31
+ __version__ = version = '0.1.6'
32
+ __version_tuple__ = version_tuple = (0, 1, 6)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1412,10 +1412,16 @@ class LineageAnalyzer:
1412
1412
  columns.extend(self._resolve_source_columns(source, select_node))
1413
1413
 
1414
1414
  # Handle JOIN clauses - collect columns from all joined tables
1415
+ # EXCEPT for SEMI and ANTI joins which only return left table columns
1415
1416
  joins = select_node.args.get("joins")
1416
1417
  if joins:
1417
1418
  for join in joins:
1418
1419
  if isinstance(join, exp.Join):
1420
+ # SEMI and ANTI joins don't include right table columns in SELECT *
1421
+ join_kind = join.kind
1422
+ if join_kind in ("SEMI", "ANTI"):
1423
+ # Skip right table columns for SEMI/ANTI joins
1424
+ continue
1419
1425
  join_source = join.this
1420
1426
  columns.extend(
1421
1427
  self._resolve_source_columns(join_source, select_node)
@@ -0,0 +1,22 @@
1
+ CREATE TEMPORARY VIEW first_view AS
2
+ SELECT
3
+ v1,
4
+ v2,
5
+ v3
6
+ FROM source_db.source_table;
7
+ CREATE TEMPORARY VIEW second_view AS WITH cte AS (
8
+ SELECT
9
+ *,
10
+ row_number() OVER (ORDER BY v1) AS row_num
11
+ FROM first_view
12
+ )
13
+
14
+ SELECT * FROM cte
15
+ WHERE row_num = 1;
16
+
17
+ INSERT INTO target_db.target_table
18
+ SELECT
19
+ v1,
20
+ v2,
21
+ v3
22
+ FROM second_view;
@@ -2766,3 +2766,57 @@ class TestLateralViewColumnResolution:
2766
2766
  # v3 schema should include columns from v1, v2, and the lateral view
2767
2767
  assert "v3" in analyzer._file_schema
2768
2768
  assert set(analyzer._file_schema["v3"].keys()) == {"id", "arr", "name", "elem"}
2769
+
2770
+
2771
+ class TestSemiAntiJoinColumnResolution:
2772
+ """Tests for SEMI and ANTI JOIN column resolution in SELECT *."""
2773
+
2774
+ def test_left_semi_join_only_returns_left_columns(self):
2775
+ """LEFT SEMI JOIN should only include columns from the left table."""
2776
+ sql = """
2777
+ CREATE VIEW v1 AS SELECT a, b FROM t1;
2778
+ CREATE VIEW v2 AS SELECT c FROM t2;
2779
+ CREATE VIEW v3 AS SELECT * FROM v1 LEFT SEMI JOIN v2 ON v1.a = v2.c;
2780
+ """
2781
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2782
+ analyzer.analyze_queries(level=AnalysisLevel.COLUMN)
2783
+
2784
+ # v3 schema should only include columns from v1 (a, b), not v2 (c)
2785
+ assert "v3" in analyzer._file_schema
2786
+ assert set(analyzer._file_schema["v3"].keys()) == {"a", "b"}
2787
+
2788
+ def test_left_anti_join_only_returns_left_columns(self):
2789
+ """LEFT ANTI JOIN should only include columns from the left table."""
2790
+ sql = """
2791
+ CREATE VIEW v1 AS SELECT a, b FROM t1;
2792
+ CREATE VIEW v2 AS SELECT c FROM t2;
2793
+ CREATE VIEW v3 AS SELECT * FROM v1 LEFT ANTI JOIN v2 ON v1.a = v2.c;
2794
+ """
2795
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2796
+ analyzer.analyze_queries(level=AnalysisLevel.COLUMN)
2797
+
2798
+ # v3 schema should only include columns from v1 (a, b), not v2 (c)
2799
+ assert "v3" in analyzer._file_schema
2800
+ assert set(analyzer._file_schema["v3"].keys()) == {"a", "b"}
2801
+
2802
+ def test_semi_join_vs_inner_join(self):
2803
+ """SEMI JOIN should behave differently from INNER JOIN for SELECT *."""
2804
+ # INNER JOIN returns columns from both tables
2805
+ sql_inner = """
2806
+ CREATE VIEW v1 AS SELECT a FROM t1;
2807
+ CREATE VIEW v2 AS SELECT b FROM t2;
2808
+ CREATE VIEW v3 AS SELECT * FROM v1 JOIN v2 ON v1.a = v2.b;
2809
+ """
2810
+ analyzer_inner = LineageAnalyzer(sql_inner, dialect="spark")
2811
+ analyzer_inner.analyze_queries(level=AnalysisLevel.COLUMN)
2812
+ assert set(analyzer_inner._file_schema["v3"].keys()) == {"a", "b"}
2813
+
2814
+ # SEMI JOIN returns only left table columns
2815
+ sql_semi = """
2816
+ CREATE VIEW v1 AS SELECT a FROM t1;
2817
+ CREATE VIEW v2 AS SELECT b FROM t2;
2818
+ CREATE VIEW v3 AS SELECT * FROM v1 LEFT SEMI JOIN v2 ON v1.a = v2.b;
2819
+ """
2820
+ analyzer_semi = LineageAnalyzer(sql_semi, dialect="spark")
2821
+ analyzer_semi.analyze_queries(level=AnalysisLevel.COLUMN)
2822
+ assert set(analyzer_semi._file_schema["v3"].keys()) == {"a"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes