sql-code-graph 1.36.0__py3-none-any.whl → 1.36.2__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.36.0
3
+ Version: 1.36.2
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
@@ -85,7 +85,8 @@ for that project.
85
85
 
86
86
  1. **Initialize**: `sqlcg db init`
87
87
  2. **Index**: `sqlcg index ./sql --dialect snowflake`
88
- 3. **Keep fresh**: `sqlcg git install-hooks` (optional)
88
+ 3. **Keep fresh**: `sqlcg git install-hooks` (auto-reindex on branch switch), or
89
+ `sqlcg watch ./sql` to re-index automatically as you edit files (both optional)
89
90
 
90
91
  ## Full setup (recommended)
91
92
 
@@ -303,7 +304,8 @@ sqlcg analyze empty-impact <table>... # downstream blast radius when named tabl
303
304
  sqlcg analyze pr-impact --base <ref> # detect producers a PR dropped + their blast radius (code-regression detection)
304
305
  sqlcg analyze upstream/downstream # trace lineage from the CLI
305
306
  sqlcg find table/column/pattern # search the graph
306
- sqlcg watch <path> # watch for file changes
307
+ sqlcg watch <path> # watch a directory and re-index on SQL file changes
308
+ sqlcg viz # generate a self-contained graph-explorer HTML
307
309
  sqlcg db info # graph stats + freshness (indexed SHA vs HEAD)
308
310
  sqlcg git install-hooks # install post-checkout + post-merge resync hooks
309
311
  sqlcg gain # show usage metrics
@@ -316,7 +318,7 @@ sqlcg mcp restart # stop the server (client must respawn it
316
318
  sqlcg version # show installed version
317
319
  ```
318
320
 
319
- ### Staying on the latest build (v1.5.0)
321
+ ### Staying on the latest build
320
322
 
321
323
  The installed package, the CLI, and the running MCP server all report the **same**
322
324
  version (`sqlcg.__version__`). After upgrading, an editor may still be talking to an
@@ -325,7 +327,7 @@ server's `version` and a `stale_by_version` flag that is `true` when the live se
325
327
  differs from the installed build. Re-running `sqlcg install` stops the stale server so
326
328
  your editor respawns it on the new build, so you never debug against an outdated server.
327
329
 
328
- ### Reads while the server is running (v1.2.0)
330
+ ### Reads while the server is running
329
331
 
330
332
  DuckDB takes an exclusive lock on the database file, so while the MCP server is
331
333
  live it holds that lock (other processes cannot open the file, even read-only).
@@ -336,6 +338,34 @@ running they open the database directly, exactly as before. If the server is
336
338
  mid-reindex the read waits for it to finish rather than failing with
337
339
  "Database is locked".
338
340
 
341
+ ### Visualising the graph (`viz`)
342
+
343
+ `sqlcg viz` generates a **self-contained graph-explorer HTML** from the live
344
+ graph — every node, edge, the force-graph library, and the facet data are inlined
345
+ into a single file, so it opens by double-click in a browser with no server or
346
+ external resources.
347
+
348
+ ```bash
349
+ sqlcg viz # writes table_graph.html in the current dir
350
+ sqlcg viz --out lineage.html # choose the output path
351
+ ```
352
+
353
+ In the browser the filter composes schema ∩ kind ∩ tag (multi-select per facet)
354
+ plus a job dropdown; an edge renders only when both endpoints are visible. Table,
355
+ view, and temp nodes are on by default; CTE and derived nodes are off (toggleable).
356
+
357
+ Two optional CSV facets let you colour and slice the graph by your own
358
+ conventions — both are `pattern,label[,color]` with a required header, patterns
359
+ are case-insensitive `fnmatch` globs (`*`, `?`) matched against the qualified
360
+ table name:
361
+
362
+ ```bash
363
+ sqlcg viz --tags tags.csv # legend swatches: colour + filter the graph
364
+ sqlcg viz --jobs jobs.csv # populate the job dropdown (filter only)
365
+ ```
366
+
367
+ Omit `--tags` to hide the tag legend; omit `--jobs` to leave the dropdown empty.
368
+
339
369
  ## Supported dialects
340
370
 
341
371
  sqlcg is built on [sqlglot](https://github.com/tobymao/sqlglot), so other dialects
@@ -1,4 +1,4 @@
1
- sqlcg/__init__.py,sha256=XPECmPOL0Clmm8vi1OTnN9oS6T6x-udm0Qb_r_tQoEA,116
1
+ sqlcg/__init__.py,sha256=lDqeTiiKtYlwFCXOBJv--TA4e7oisecgTT3NeETH6eY,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
@@ -44,7 +44,7 @@ sqlcg/lineage/schema_resolver.py,sha256=iXt6LYF6UVWsGUpcfbmjmGn9wCgXl721lTGf_8Aa
44
44
  sqlcg/metrics/__init__.py,sha256=hLJ6wm4St8qqYwKh3o9QG7lcEt1BEYM31ccqO9tGpIg,133
45
45
  sqlcg/metrics/store.py,sha256=KuDtxvyAgug9_KtiSCpvgKM2VZM7VSaI3D11uMLjJJk,10604
46
46
  sqlcg/parsers/__init__.py,sha256=AamA8wBbDZV9_zEtZCI4Hyen5UAVKHmBwjTghTt2PZE,785
47
- sqlcg/parsers/ansi_parser.py,sha256=RX6eVj7gt1qmsHNJLAF_a4jyW3RCI5W2oF4rd53cKNg,39336
47
+ sqlcg/parsers/ansi_parser.py,sha256=7pudMxij87m419OcCzmaus124x2vHJ62bIGhBTBlZDw,40348
48
48
  sqlcg/parsers/base.py,sha256=d5s5_LSv96jrww9vx52GujjrLHwpxy_UOhmIlWcKglw,106489
49
49
  sqlcg/parsers/bigquery_parser.py,sha256=g0B6aIpMyxLMVQ3ohAAjzR4nEmMh-WGkFcYLMiKdLxs,3177
50
50
  sqlcg/parsers/dynamic_name.py,sha256=q0QAa9iAcmRW4e_0G2b2j-xTbI3VR1-Wwa-nJRLtrQw,6836
@@ -73,7 +73,7 @@ sqlcg/viz/render.py,sha256=BINkGbJbbb_iqhrkN795RaQsdg8nqCiJtsEFF1yo22Y,2737
73
73
  sqlcg/viz/tags.py,sha256=6zRnGlHjuGmEeB6yN1uhzm8rqL7ZGoyL1Ki7jI5oM6A,5368
74
74
  sqlcg/viz/assets/force-graph.min.js,sha256=jNdYdDdrYiUdUlElxRkolPBt30rstQk2q15Q32VVdzc,177272
75
75
  sqlcg/viz/assets/template.html,sha256=9_j-mvo1ZxwgiJPDdVrNmca37dTrTjjYVd3977u-DxE,12294
76
- sql_code_graph-1.36.0.dist-info/METADATA,sha256=qmHQutd2-IfpHk1ETAPDISdRiprgHJSe8DvFQokUOa8,17791
77
- sql_code_graph-1.36.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
78
- sql_code_graph-1.36.0.dist-info/entry_points.txt,sha256=Wfe49sVzV9p4eVFGo5RxcV-frr3HOP0yzzst8JBxQLQ,46
79
- sql_code_graph-1.36.0.dist-info/RECORD,,
76
+ sql_code_graph-1.36.2.dist-info/METADATA,sha256=if10KHC8utK49r0BY4N9DmsK98-Uz1mUlauVqTiFEaE,19208
77
+ sql_code_graph-1.36.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
78
+ sql_code_graph-1.36.2.dist-info/entry_points.txt,sha256=Wfe49sVzV9p4eVFGo5RxcV-frr3HOP0yzzst8JBxQLQ,46
79
+ sql_code_graph-1.36.2.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.36.0"
3
+ __version__ = "1.36.2"
4
4
 
5
5
  __all__ = ["__version__"]
@@ -564,12 +564,26 @@ class AnsiParser(SqlParser):
564
564
  # DML (a separate node the gate never touches), so gating PROCEDURE is
565
565
  # edge-neutral. This single gate feeds all three
566
566
  # `referenced_tables.extend(query_node.sources)` sites
567
- # (ansi_parser.py:246, snowflake_parser.py:784 / :944).
567
+ # (ansi_parser.py:246, snowflake_parser.py:894 / :1054).
568
568
  is_non_table_create = isinstance(stmt, exp.Create) and stmt.kind not in ("TABLE", "VIEW")
569
569
 
570
+ # Phantom source-node gate part 2 (#161 part 2,
571
+ # plan/sprints/fix_drop_alter_phantom_source_node.md): DROP / ALTER /
572
+ # TRUNCATE reference their TARGET object, not a data-flow source. No SELECT
573
+ # body is structurally possible, so build_scope() returns None for them and
574
+ # _fallback_table_scan below would otherwise scoop the target name into
575
+ # `sources`, minting a phantom degree-0 island SqlTable node + a phantom
576
+ # SELECTS_FROM edge (measured: 169 sole-DROP/ALTER/TRUNCATE-origin nodes,
577
+ # 1,308 phantom SELECTS_FROM edges on the DWH corpus). Keyed off the AST
578
+ # type (independent of _classify/QueryKind), and PER-STATEMENT: a table
579
+ # legitimately created/read by a *different* statement keeps its node + real
580
+ # edges; only the source the DROP/ALTER/TRUNCATE statement would have
581
+ # contributed is suppressed.
582
+ is_non_flow_ddl = isinstance(stmt, (exp.Drop, exp.Alter, exp.TruncateTable))
583
+
570
584
  # Try to extract table references using scope analysis
571
585
  try:
572
- if is_non_table_create:
586
+ if is_non_table_create or is_non_flow_ddl:
573
587
  sources = []
574
588
  else:
575
589
  # Use pre-built scope if provided, otherwise build it here (fallback)