sql-glider 0.1.8__tar.gz → 0.1.9__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.8 → sql_glider-0.1.9}/PKG-INFO +1 -1
  2. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/_version.py +2 -2
  3. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/lineage/analyzer.py +22 -0
  4. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/lineage/test_analyzer.py +86 -0
  5. {sql_glider-0.1.8 → sql_glider-0.1.9}/.github/workflows/ci.yml +0 -0
  6. {sql_glider-0.1.8 → sql_glider-0.1.9}/.github/workflows/publish.yml +0 -0
  7. {sql_glider-0.1.8 → sql_glider-0.1.9}/.gitignore +0 -0
  8. {sql_glider-0.1.8 → sql_glider-0.1.9}/.python-version +0 -0
  9. {sql_glider-0.1.8 → sql_glider-0.1.9}/ARCHITECTURE.md +0 -0
  10. {sql_glider-0.1.8 → sql_glider-0.1.9}/CLAUDE.md +0 -0
  11. {sql_glider-0.1.8 → sql_glider-0.1.9}/LICENSE +0 -0
  12. {sql_glider-0.1.8 → sql_glider-0.1.9}/README.md +0 -0
  13. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-05-column-level-lineage.md +0 -0
  14. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-05-reverse-lineage.md +0 -0
  15. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-06-config-file-support.md +0 -0
  16. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-06-graph-lineage.md +0 -0
  17. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-06-unify-single-multi-query.md +0 -0
  18. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-07-sample-data-model.md +0 -0
  19. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-07-sql-templating.md +0 -0
  20. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-08-tables-command.md +0 -0
  21. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-09-graph-query-paths.md +0 -0
  22. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-13-dissect-command.md +0 -0
  23. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2025-12-14-tables-pull-command.md +0 -0
  24. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
  25. {sql_glider-0.1.8 → sql_glider-0.1.9}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
  26. {sql_glider-0.1.8 → sql_glider-0.1.9}/pyproject.toml +0 -0
  27. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/README.md +0 -0
  28. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/expire_dim_customer.sql +0 -0
  29. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/load_fact_orders.sql +0 -0
  30. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/load_fact_payments.sql +0 -0
  31. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/merge_dim_customer.sql +0 -0
  32. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/merge_dim_product.sql +0 -0
  33. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
  34. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/complex/conditional_merge.sql +0 -0
  35. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/complex/cte_insert.sql +0 -0
  36. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/complex/multi_table_transform.sql +0 -0
  37. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/dim_customer.sql +0 -0
  38. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/dim_product.sql +0 -0
  39. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/fact_orders.sql +0 -0
  40. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/fact_payments.sql +0 -0
  41. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_addresses.sql +0 -0
  42. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_customers.sql +0 -0
  43. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_order_items.sql +0 -0
  44. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_orders.sql +0 -0
  45. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_payments.sql +0 -0
  46. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/raw_products.sql +0 -0
  47. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/stg_customers.sql +0 -0
  48. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/stg_orders.sql +0 -0
  49. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/stg_payments.sql +0 -0
  50. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/ddl/stg_products.sql +0 -0
  51. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
  52. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
  53. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
  54. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
  55. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/maintenance/update_product_status.sql +0 -0
  56. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
  57. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
  58. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
  59. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
  60. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/staging/load_stg_customers.sql +0 -0
  61. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/staging/load_stg_orders.sql +0 -0
  62. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/staging/load_stg_payments.sql +0 -0
  63. {sql_glider-0.1.8 → sql_glider-0.1.9}/sample_data_model/staging/load_stg_products.sql +0 -0
  64. {sql_glider-0.1.8 → sql_glider-0.1.9}/sqlglider.toml.example +0 -0
  65. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/__init__.py +0 -0
  66. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/catalog/__init__.py +0 -0
  67. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/catalog/base.py +0 -0
  68. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/catalog/databricks.py +0 -0
  69. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/catalog/registry.py +0 -0
  70. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/cli.py +0 -0
  71. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/dissection/__init__.py +0 -0
  72. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/dissection/analyzer.py +0 -0
  73. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/dissection/formatters.py +0 -0
  74. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/dissection/models.py +0 -0
  75. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/global_models.py +0 -0
  76. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/__init__.py +0 -0
  77. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/builder.py +0 -0
  78. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/merge.py +0 -0
  79. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/models.py +0 -0
  80. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/query.py +0 -0
  81. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/graph/serialization.py +0 -0
  82. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/lineage/__init__.py +0 -0
  83. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/lineage/formatters.py +0 -0
  84. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/templating/__init__.py +0 -0
  85. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/templating/base.py +0 -0
  86. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/templating/jinja.py +0 -0
  87. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/templating/registry.py +0 -0
  88. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/templating/variables.py +0 -0
  89. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/utils/__init__.py +0 -0
  90. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/utils/config.py +0 -0
  91. {sql_glider-0.1.8 → sql_glider-0.1.9}/src/sqlglider/utils/file_utils.py +0 -0
  92. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/__init__.py +0 -0
  93. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
  94. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
  95. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/customers.sql +0 -0
  96. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/orders.sql +0 -0
  97. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/reports.sql +0 -0
  98. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
  99. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_cte.sql +0 -0
  100. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
  101. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
  102. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
  103. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_multi.sql +0 -0
  104. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
  105. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_single_query.sql +0 -0
  106. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_subquery.sql +0 -0
  107. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_tables.sql +0 -0
  108. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_view.sql +0 -0
  109. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
  110. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/fixtures/sample_manifest.csv +0 -0
  111. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/__init__.py +0 -0
  112. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/catalog/__init__.py +0 -0
  113. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/catalog/test_base.py +0 -0
  114. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/catalog/test_databricks.py +0 -0
  115. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/catalog/test_registry.py +0 -0
  116. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/dissection/__init__.py +0 -0
  117. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/dissection/test_analyzer.py +0 -0
  118. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/dissection/test_formatters.py +0 -0
  119. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/dissection/test_models.py +0 -0
  120. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/__init__.py +0 -0
  121. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/test_builder.py +0 -0
  122. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/test_merge.py +0 -0
  123. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/test_models.py +0 -0
  124. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/test_query.py +0 -0
  125. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/graph/test_serialization.py +0 -0
  126. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/lineage/__init__.py +0 -0
  127. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/lineage/test_formatters.py +0 -0
  128. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/templating/__init__.py +0 -0
  129. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/templating/test_base.py +0 -0
  130. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/templating/test_jinja.py +0 -0
  131. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/templating/test_registry.py +0 -0
  132. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/templating/test_variables.py +0 -0
  133. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/test_cli.py +0 -0
  134. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/utils/__init__.py +0 -0
  135. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/utils/test_config.py +0 -0
  136. {sql_glider-0.1.8 → sql_glider-0.1.9}/tests/sqlglider/utils/test_file_utils.py +0 -0
  137. {sql_glider-0.1.8 → sql_glider-0.1.9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-glider
3
- Version: 0.1.8
3
+ Version: 0.1.9
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/
@@ -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.8'
32
- __version_tuple__ = version_tuple = (0, 1, 8)
31
+ __version__ = version = '0.1.9'
32
+ __version_tuple__ = version_tuple = (0, 1, 9)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -615,6 +615,12 @@ class LineageAnalyzer:
615
615
  if isinstance(target, exp.Table):
616
616
  return (self._get_qualified_table_name(target), ObjectType.UNKNOWN)
617
617
 
618
+ # CACHE TABLE
619
+ elif isinstance(self.expr, exp.Cache):
620
+ target = self.expr.this
621
+ if isinstance(target, exp.Table):
622
+ return (self._get_qualified_table_name(target), ObjectType.TABLE)
623
+
618
624
  # DELETE FROM table
619
625
  elif isinstance(self.expr, exp.Delete):
620
626
  target = self.expr.this
@@ -706,6 +712,10 @@ class LineageAnalyzer:
706
712
  elif isinstance(self.expr, exp.Drop):
707
713
  return table_node is self.expr.this
708
714
 
715
+ # For CACHE TABLE, the target is self.expr.this
716
+ elif isinstance(self.expr, exp.Cache):
717
+ return table_node is self.expr.this
718
+
709
719
  return False
710
720
 
711
721
  def _analyze_column_lineage_internal(
@@ -889,6 +899,7 @@ class LineageAnalyzer:
889
899
  "Drop": f"DROP {getattr(target_expr, 'kind', '')}".strip(),
890
900
  "Alter": "ALTER",
891
901
  "Truncate": "TRUNCATE",
902
+ "Cache": "CACHE TABLE",
892
903
  "Command": "COMMAND",
893
904
  }
894
905
 
@@ -943,6 +954,17 @@ class LineageAnalyzer:
943
954
  ):
944
955
  return (target_name, select_node)
945
956
 
957
+ # Check for CACHE TABLE AS SELECT
958
+ elif isinstance(self.expr, exp.Cache):
959
+ target = self.expr.this
960
+ if isinstance(target, exp.Table):
961
+ target_name = self._get_qualified_table_name(target)
962
+ select_node = self.expr.expression
963
+ if isinstance(
964
+ select_node, (exp.Select, exp.Union, exp.Intersect, exp.Except)
965
+ ):
966
+ return (target_name, select_node)
967
+
946
968
  # Check for MERGE statement
947
969
  elif isinstance(self.expr, exp.Merge):
948
970
  target = self.expr.this
@@ -2820,3 +2820,89 @@ class TestSemiAntiJoinColumnResolution:
2820
2820
  analyzer_semi = LineageAnalyzer(sql_semi, dialect="spark")
2821
2821
  analyzer_semi.analyze_queries(level=AnalysisLevel.COLUMN)
2822
2822
  assert set(analyzer_semi._file_schema["v3"].keys()) == {"a"}
2823
+
2824
+
2825
+ class TestCacheTableStatements:
2826
+ """Tests for Spark SQL CACHE TABLE statement support."""
2827
+
2828
+ def test_cache_table_as_select_column_lineage(self):
2829
+ """CACHE TABLE t AS SELECT should produce lineage with t as target."""
2830
+ sql = """
2831
+ CACHE TABLE cached_customers AS
2832
+ SELECT customer_id, customer_name FROM customers
2833
+ """
2834
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2835
+ results = analyzer.analyze_queries(level=AnalysisLevel.COLUMN)
2836
+
2837
+ assert len(results) == 1
2838
+ output_names = [item.output_name for item in results[0].lineage_items]
2839
+ assert any("cached_customers" in name for name in output_names)
2840
+ assert any("customer_id" in name for name in output_names)
2841
+ assert any("customer_name" in name for name in output_names)
2842
+
2843
+ def test_cache_table_as_select_table_extraction(self):
2844
+ """CACHE TABLE t AS SELECT should show cached_orders as OUTPUT table."""
2845
+ sql = """
2846
+ CACHE TABLE cached_orders AS
2847
+ SELECT order_id, total FROM orders
2848
+ """
2849
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2850
+ results = analyzer.analyze_tables()
2851
+
2852
+ assert len(results) == 1
2853
+ tables_by_name = {t.name: t for t in results[0].tables}
2854
+
2855
+ assert "cached_orders" in tables_by_name
2856
+ assert tables_by_name["cached_orders"].usage.value == "OUTPUT"
2857
+ assert tables_by_name["cached_orders"].object_type.value == "TABLE"
2858
+
2859
+ assert "orders" in tables_by_name
2860
+ assert tables_by_name["orders"].usage.value == "INPUT"
2861
+
2862
+ def test_cache_table_as_select_with_join(self):
2863
+ """CACHE TABLE with a JOIN query should trace all sources."""
2864
+ sql = """
2865
+ CACHE TABLE summary AS
2866
+ SELECT c.customer_id, o.total
2867
+ FROM customers c
2868
+ JOIN orders o ON c.id = o.customer_id
2869
+ """
2870
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2871
+ results = analyzer.analyze_tables()
2872
+
2873
+ assert len(results) == 1
2874
+ tables_by_name = {t.name: t for t in results[0].tables}
2875
+
2876
+ assert "summary" in tables_by_name
2877
+ assert tables_by_name["summary"].usage.value == "OUTPUT"
2878
+ assert "customers" in tables_by_name
2879
+ assert tables_by_name["customers"].usage.value == "INPUT"
2880
+ assert "orders" in tables_by_name
2881
+ assert tables_by_name["orders"].usage.value == "INPUT"
2882
+
2883
+ def test_bare_cache_table_is_skipped(self):
2884
+ """CACHE TABLE t (without AS SELECT) should be skipped."""
2885
+ sql = "CACHE TABLE my_table"
2886
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2887
+ results = analyzer.analyze_queries(level=AnalysisLevel.COLUMN)
2888
+
2889
+ assert len(results) == 0
2890
+ skipped = analyzer.skipped_queries
2891
+ assert len(skipped) == 1
2892
+ assert "CACHE" in skipped[0].statement_type
2893
+
2894
+ def test_cache_table_in_multi_query(self):
2895
+ """CACHE TABLE should work alongside other statements in multi-query files."""
2896
+ sql = """
2897
+ SELECT id FROM users;
2898
+ CACHE TABLE cached_orders AS SELECT order_id FROM orders;
2899
+ DELETE FROM old_data;
2900
+ """
2901
+ analyzer = LineageAnalyzer(sql, dialect="spark")
2902
+ results = analyzer.analyze_queries(level=AnalysisLevel.COLUMN)
2903
+
2904
+ # SELECT and CACHE TABLE should produce results; DELETE is skipped
2905
+ assert len(results) == 2
2906
+ skipped = analyzer.skipped_queries
2907
+ assert len(skipped) == 1
2908
+ assert "DELETE" in skipped[0].statement_type
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