sql-code-graph 1.34.2__py3-none-any.whl → 1.34.4__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-code-graph
3
- Version: 1.34.2
3
+ Version: 1.34.4
4
4
  Summary: SQL code graph analyzer and lineage tracer
5
5
  Project-URL: Homepage, https://github.com/Warhorze/sql-code-graph
6
6
  Project-URL: Repository, https://github.com/Warhorze/sql-code-graph
@@ -1,10 +1,10 @@
1
- sqlcg/__init__.py,sha256=X0KIBt_EAEReYxinGfqCekhZfuig2-2wMaiFhcqovgM,116
1
+ sqlcg/__init__.py,sha256=jFojpr6ZojswTJKMfPZEdxqOfiqZPTpuB2Cb9aa1RM0,116
2
2
  sqlcg/__main__.py,sha256=1YoFLcqEgTwYq1J3TbUwpkdG0zeeLIf2fJvwWI-CLFU,109
3
3
  sqlcg/cli/__init__.py,sha256=W8fD0LpMq2xm_5WKGNMvJh2WBL1ho5E8hUeAqXQYT1g,28
4
4
  sqlcg/cli/coverage.py,sha256=Xm9ITzZDHv2mJ70Q5jCacVuhDStVrE3gq12_-Ypvtd8,43823
5
5
  sqlcg/cli/main.py,sha256=tlFvl-l9hWfZBP9dO2svZXvLDbh7T5731CFyctuVqDI,2485
6
6
  sqlcg/cli/commands/__init__.py,sha256=oSHtr6VD-jNubOjuCQyZj2tBppjMEpQDh-IGQ8of9eA,30
7
- sqlcg/cli/commands/analyze.py,sha256=XMax3uHyNEe8SIMEhiLBdtbQb8QUwncoQKTB2LIT3Vg,30000
7
+ sqlcg/cli/commands/analyze.py,sha256=lC7QeBKljWVpKQ-x8BOF5Ok6y4jd329U1aBGrp159OA,31046
8
8
  sqlcg/cli/commands/catalog.py,sha256=xCIWp_9xcDPHIMUB0xrZR3-G0WMvKbfq4yMwe2sDT2g,12670
9
9
  sqlcg/cli/commands/db.py,sha256=QEDPs0boeFe8ETE8BWe7I2JLSXROUI571SHXMTUqxh8,7982
10
10
  sqlcg/cli/commands/find.py,sha256=uMdG08bU-AvB9RqsTKPfdVnJet7b3Ebj0xbsjqTclYA,2678
@@ -25,15 +25,15 @@ sqlcg/core/graph_db.py,sha256=3iZ1J32cEn7_cVhNA1tLiNuJHCyatN4F40HXLLfmwHY,10815
25
25
  sqlcg/core/jobs.py,sha256=Je-fCdSKRgiSsv1W8SgNAlp36a7t7-pJZ-qKPbka9OE,3298
26
26
  sqlcg/core/noise_match.py,sha256=8jxMBum0HB7wnVyS8hHaklO279QOSNKDmPtv-0RujD8,4781
27
27
  sqlcg/core/queries.cypher,sha256=cvPOVe5GUOzJN4bxUvDxNI--xIIP8gm42TR-gUnea4U,4685
28
- sqlcg/core/queries.py,sha256=mxpG_zBENG7kcoz3YolMvHv7s_HagWluakTUw3nYSts,3631
29
- sqlcg/core/queries.sql,sha256=gT8vl7CgOUZXjElpMZrHvuE_bs2ZJ4FLFA83EKaeRWM,15601
28
+ sqlcg/core/queries.py,sha256=QwQsjI2YJPipfw69k9iSu1jpeiOIPPtkegO4TVmAVaY,3703
29
+ sqlcg/core/queries.sql,sha256=-ZoMnNt-i2kojMHLAUHvQhCZURIgI9zkfh8J8QJo1iE,16863
30
30
  sqlcg/core/schema.cypher,sha256=StaJqIzOLwF2X9HYvfHSdGiYGFb_YkiHubPrTu-Qpmg,2898
31
31
  sqlcg/core/schema.py,sha256=pVGzf__czAddmz-fsXgXqq2DTxN9EKom5RvIHLctIPU,1519
32
32
  sqlcg/indexer/__init__.py,sha256=Wh20Unz2OHs1oIyWLrpurPAasF0BET2g4iXtNk7mh2U,56
33
33
  sqlcg/indexer/dbt_adapter.py,sha256=EB5x1WU5Z9d-I97ADDj88S_hG1C4z4nbrv8JUCzXfy8,686
34
34
  sqlcg/indexer/error_classify.py,sha256=-sp8cRmuOBHu_CxnCtaXf34YxHFYwIFNjIrn4LaEv6M,7142
35
35
  sqlcg/indexer/git_delta.py,sha256=zYdH5q-jV7w_ne8Oxdywsy0N3rwUjpd5RjEDurlrMSA,5026
36
- sqlcg/indexer/indexer.py,sha256=de-3aYaAP_EdG-bwtFwp4e2NGKw6kpDpxb_wsOsQhdU,101712
36
+ sqlcg/indexer/indexer.py,sha256=u6fIhgLfBs9fKJoAyO4hJrm9152YMe08EHycncctQx8,102697
37
37
  sqlcg/indexer/pool.py,sha256=iMmCQtpDRKBTQBep2_EUq9THcsE18Zgk0hdaFB_CwiA,19006
38
38
  sqlcg/indexer/walker.py,sha256=Cft6JiJtdBFy0HR6L9pJdr5Fg0eRR3XBW1OMtM2apto,1947
39
39
  sqlcg/indexer/watcher.py,sha256=mJQq1LASRLKKwhz0WhCUWPLLqyPR2_-FD_8efYU6gE8,8442
@@ -65,7 +65,7 @@ sqlcg/utils/__init__.py,sha256=--iqt5ThTXmT8Wz7da8hs3n0zDfYPl8P-z5OgRJ_77E,154
65
65
  sqlcg/utils/hashing.py,sha256=H25-sYfxHKb3_IERFnHyAIYNiXN470Oqo5sJT_D3YOA,438
66
66
  sqlcg/utils/ignore.py,sha256=6__DfiYgynI2b8nH52O2BzI1EZcZ_LRazhqEOJVGGcE,1955
67
67
  sqlcg/utils/logging.py,sha256=u0fCmYsLj9o81vawm3xZTHaw68GQYVm7JxG-gP81u8A,840
68
- sql_code_graph-1.34.2.dist-info/METADATA,sha256=lzFJzaaXoplO-E4EkNdFhHjZXdet3GBEWqnTtm9JCmQ,17791
69
- sql_code_graph-1.34.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
70
- sql_code_graph-1.34.2.dist-info/entry_points.txt,sha256=Wfe49sVzV9p4eVFGo5RxcV-frr3HOP0yzzst8JBxQLQ,46
71
- sql_code_graph-1.34.2.dist-info/RECORD,,
68
+ sql_code_graph-1.34.4.dist-info/METADATA,sha256=tzuVGUb49jlzRUkFgV28LwMdvIR0h83TsN9zpFHFA0A,17791
69
+ sql_code_graph-1.34.4.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
70
+ sql_code_graph-1.34.4.dist-info/entry_points.txt,sha256=Wfe49sVzV9p4eVFGo5RxcV-frr3HOP0yzzst8JBxQLQ,46
71
+ sql_code_graph-1.34.4.dist-info/RECORD,,
sqlcg/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """SQL Code Graph - SQL lineage and dependency analysis tool."""
2
2
 
3
- __version__ = "1.34.2"
3
+ __version__ = "1.34.4"
4
4
 
5
5
  __all__ = ["__version__"]
@@ -8,7 +8,10 @@ import typer
8
8
  from rich.console import Console
9
9
  from rich.table import Table
10
10
 
11
- from sqlcg.core.queries import GET_TABLE_EXTERNAL_CONSUMERS_QUERY
11
+ from sqlcg.core.queries import (
12
+ GET_TABLE_EXTERNAL_CONSUMERS_QUERY,
13
+ IMPACT_CONSUMERS_VIA_LINEAGE_QUERY,
14
+ )
12
15
  from sqlcg.server.read_client import resolved_repo_root, run_read_routed
13
16
 
14
17
  if TYPE_CHECKING:
@@ -312,8 +315,16 @@ def impact( # noqa: B008
312
315
  table: str = typer.Argument(..., help="Table name to analyze"), # noqa: B008
313
316
  raw: bool = typer.Option(False, "--raw", help="Disable noise filtering on results"), # noqa: B008
314
317
  ) -> None:
315
- """Show all queries impacted by a table."""
316
- results = run_read_routed(
318
+ """Show all queries impacted by a table.
319
+
320
+ One-hop "who reads this table" — the union of direct SELECTS_FROM consumers
321
+ and consumers that read the table only via COLUMN_LINEAGE / STAR_SOURCE
322
+ (CTE-wrapped / promoted-intermediate reads, e.g. the live DWH node
323
+ ``ba.all_rows_in_selection``). Bug #6 fix: brings ``impact`` to the same
324
+ one-hop consumer completeness ``find_table_usages`` already has. Stays
325
+ one-hop (NOT transitive — that is ``downstream``'s job).
326
+ """
327
+ direct = run_read_routed(
317
328
  "SELECT DISTINCT q.id AS id, q.kind AS kind, q.target_table AS target"
318
329
  ' FROM "SqlTable" t'
319
330
  ' JOIN "SELECTS_FROM" sf ON sf.dst_key = t.qualified'
@@ -321,6 +332,17 @@ def impact( # noqa: B008
321
332
  " WHERE t.qualified = ? LIMIT 100",
322
333
  {"t": table},
323
334
  )
335
+ # Consumers reachable only via COLUMN_LINEAGE / STAR_SOURCE. Two "?" both
336
+ # bound to the qualified table name: _params_list returns list(values()) in
337
+ # insertion order, so the ordered dict {"t":..., "t2":...} binds correctly.
338
+ via = run_read_routed(
339
+ IMPACT_CONSUMERS_VIA_LINEAGE_QUERY,
340
+ {"t": table, "t2": table},
341
+ )
342
+ seen = {r["id"] for r in direct}
343
+ results = direct + [r for r in via if r["id"] not in seen]
344
+ # Preserve the existing 100-row bound on the merged consumer set.
345
+ results = results[:100]
324
346
  if not raw:
325
347
  from sqlcg.server.noise_filter import NoiseFilter
326
348
 
sqlcg/core/queries.py CHANGED
@@ -72,3 +72,4 @@ GET_TABLES_EXTERNAL_CONSUMERS_BATCH_QUERY = _Q["GET_TABLES_EXTERNAL_CONSUMERS_BA
72
72
  COUNT_EXTERNAL_CONSUMERS_QUERY = _Q["COUNT_EXTERNAL_CONSUMERS"]
73
73
  GET_TABLE_READS_ADJACENCY_QUERY = _Q["GET_TABLE_READS_ADJACENCY"]
74
74
  GET_PRODUCER_TABLES_QUERY = _Q["GET_PRODUCER_TABLES"]
75
+ IMPACT_CONSUMERS_VIA_LINEAGE_QUERY = _Q["IMPACT_CONSUMERS_VIA_LINEAGE"]
sqlcg/core/queries.sql CHANGED
@@ -413,3 +413,26 @@ WHERE t.name = ?
413
413
  SELECT DISTINCT target_table AS producer_table
414
414
  FROM "SqlQuery"
415
415
  WHERE target_table <> '' AND target_table IS NOT NULL
416
+
417
+ -- IMPACT_CONSUMERS_VIA_LINEAGE
418
+ -- Bug #6: consumers that read a table only via COLUMN_LINEAGE or STAR_SOURCE
419
+ -- (CTE-wrapped / promoted-intermediate reads that emit no top-level SELECTS_FROM
420
+ -- edge, e.g. the live DWH cross-file-promoted node ba.all_rows_in_selection:
421
+ -- kind='table', non-namespaced, 0 SELECTS_FROM in-edges, 55 COLUMN_LINEAGE
422
+ -- out-edges). Returns the same (id, kind, target) shape as the SELECTS_FROM-only
423
+ -- impact query in analyze.py:impact() so the two result sets merge + dedup on q.id.
424
+ -- Both branches key on the QUALIFIED table name (impact() keys on t.qualified):
425
+ -- COLUMN_LINEAGE branch -> src.table_qualified; STAR_SOURCE branch -> ss.dst_key.
426
+ -- The STAR_SOURCE branch closes the STAR-only-consumer gap (FIND_TABLE_USAGES
427
+ -- itself still lacks it — out of scope, separate follow-up).
428
+ -- params: [table_qualified, table_qualified] (same value bound to BOTH ?)
429
+ SELECT DISTINCT q.id AS id, q.kind AS kind, q.target_table AS target
430
+ FROM "SqlColumn" src
431
+ JOIN "COLUMN_LINEAGE" cl ON cl.src_key = src.id
432
+ JOIN "SqlQuery" q ON q.id = cl.query_id
433
+ WHERE src.table_qualified = ?
434
+ UNION
435
+ SELECT DISTINCT q.id AS id, q.kind AS kind, q.target_table AS target
436
+ FROM "STAR_SOURCE" ss
437
+ JOIN "SqlQuery" q ON q.id = ss.src_key
438
+ WHERE ss.dst_key = ?
sqlcg/indexer/indexer.py CHANGED
@@ -896,6 +896,20 @@ class Indexer:
896
896
  if profile:
897
897
  _t_catalog_end = time.perf_counter()
898
898
 
899
+ # Bug #4 (PR-4): re-run the star expansion AFTER the catalog is applied.
900
+ # The first pass at the top of this block expands STAR_SOURCE rows whose
901
+ # leaf table already had HAS_COLUMN rows (parsed DDL). A temp built as
902
+ # `CREATE TEMP t AS SELECT * FROM src` where `src` is catalogued ONLY via
903
+ # information_schema has NO columns at the first pass — its HAS_COLUMN rows
904
+ # arrive with the catalog above — so the temp (and any promote out of it)
905
+ # produced zero edges. The star-expansion SQL is idempotent
906
+ # (INSERT OR REPLACE) and chains both levels (src -> temp -> persisted) in a
907
+ # single pass once the leaf columns exist, so one extra invocation here is
908
+ # the full fix. Only re-run when the catalog actually added columns; a repo
909
+ # with no configured catalog pays nothing.
910
+ if catalog_result.get("columns_loaded", 0) > 0:
911
+ star_edges_expanded = self._expand_star_sources(db)
912
+
899
913
  # Post-catalog: resolve JOIN_COL_RESOLVE markers against the full HAS_COLUMN
900
914
  # catalog (Bug #5, PR-5 option b). MUST run after the catalog is applied so
901
915
  # information_schema columns are present; the suppressed sqlglot mis-bind