Skip to content

feat: 无 CREATE SEQUENCE 时为 seq.nextval 建 inferred seq* + UsesSequence(对齐 table*) - #160

Merged
c2j merged 6 commits into
mainfrom
feat/issue-159
Sep 8, 2026
Merged

c2j merged 6 commits into
mainfrom
feat/issue-159

Conversation

@c2j

@c2j c2j commented Sep 7, 2026

Copy link
Copy Markdown
Owner

摘要

Closes #159

seq.nextval 被引用但分析范围内无 CREATE SEQUENCE DDL 时,builder 此前静默丢弃 UsesSequence 边。本 PR 对齐 table* 既有模式:创建 inferred seq* 节点并挂边,使 detail / impact 在缺 DDL 时仍能看到真实序列依赖。

主要改动

  • src/graph/mod.rsNode::Sequence 增加 #[serde(default)] explicit: boollocation 改为 Option<SourceLocation>(完全镜像 Table/View);node_type_tag 增加 seq*Node::file() 适配 Option(消除 inferred 节点 panic 路径)
  • src/graph/builder.rs — 3 处 lookup-miss-即-丢(procedure / function / package member)收敛为共享 resolve_or_infer_sequence:DDL 缺失时 or_insert inferred 节点;schema 限定引用仅精确匹配 full key,不回退短名别名,避免 hr.seq_id 误绑定 finance.seq_id(跨 schema 误绑定 bug 在 code review 中发现并已修复,含 2 个回归测试)
  • src/graph/store.rsSTORE_VERSION 8 → 9(bincode 变体形状变更,版本门禁触发旧 store 自动重建)
  • src/main.rsis_inferred_node 覆盖 inferred sequence,detail 自动显示 ⚠ inferred node
  • src/export/json.rsNodeKindJson::Sequence 对齐 Table 的 skip_serializing_if 惯例(explicit/file/line
  • src/import/parser.rs — CGEF 导入的 sequence 设 explicit: true

测试

新增 10 个测试(TDD Red→Green):

单元(builder.rs):无 DDL 建 inferred 节点、有 DDL 恰好 1 条边不重复、SELECT seq.nextval INTO ... FROM sys_dummy 两路径、赋值/INSERT 形态、schema 限定回退、跨 schema 不误绑定 ×2
其他:seq* 标签、version=8 store 被版本门禁拒绝、集成回归(落盘/增量无重复/JSON 形状)

既有 2 个人类测试(procedure_using_nextval_creates_uses_sequence_edge 等)未改动,保持通过。

验证

cargo fmt --all -- --check                                    ✅
cargo build --features full                                   ✅
cargo clippy --features full -- -D warnings                   ✅ 0 warning
cargo test --features full -- --skip test_path_mapping_applied --skip test_serve_
                                                              ✅ 全套件 0 failed

范围外(per issue)

  • 不改 sys_dummy/dual 是否出现在 detail 默认 CALLEES
  • 不把 sequence 编进 lineage 数据流
  • 已知 follow-up:main.rs 重复的 node_type_tag 对既有 table*/view* 不带 *(pre-existing,未在本 PR 扩大范围)

🤖 Generated with Sisyphus

Comment thread src/graph/builder.rs Outdated
type_index: &HashMap<String, petgraph::graph::NodeIndex>,
sequence_index: &HashMap<String, petgraph::graph::NodeIndex>,
) {
let mut inferred_sequence_index = HashMap::new();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[bug] inferred_sequence_index is a local HashMap created at the start of each create_object_ref_edges call and never written into GraphBuildContext.sequence_index. Project::analyze parses SQL in chunks of 100 (DEFAULT_SQL_CHUNK_SIZE) and calls build_sql_chunk per chunk, so the cache does not survive chunk boundaries. Tables avoid this by inserting inferred nodes into the shared table_index and by upgrading in place on CREATE TABLE (explicit = true, location = Some(...)). Sequences do neither: a later chunk that sees the same nextval/seq.nextval allocates a second seq* node, and a later CREATE SEQUENCE only checks sequence_index.contains_key(&full_key) (builder.rs:650) so it adds a sibling explicit node instead of promoting the inferred one. finalize_graph runs dedup_table_view_nodes but has no sequence equivalent, and pick_richer_node has no Node::Sequence arm, so codeweb dedup would keep the first (often inferred) node. Single-file unit tests and the issue-159 integration test never exercise two build_sql_chunk calls, so this is uncaught.

Suggestion: Keep inferred sequence lookups on GraphBuildContext (either mutate sequence_index or add a context-level inferred map) so later chunks reuse the same NodeIndex. Mirror CREATE TABLE: if a matching inferred node already exists, set explicit: true and location: Some(...) instead of add_node. Extend pick_richer_node to prefer Node::Sequence { explicit: true, location: Some(_), .. } over inferred. Add a two-chunk test in the style of qualified_table_into_view_merged_then_bare_into_qualified: chunk 1 references my_seq.nextval with no DDL, chunk 2 either repeats the ref or adds CREATE SEQUENCE my_seq, then finalize_graph and assert a single sequence node (and, in the DDL case, explicit: true).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修复(76725a8 + 4b0ffd4):

  1. ctx 级缓存inferred_sequence_index 提升为 GraphBuildContext 字段(兄弟 map,不混入 sequence_index),create_object_ref_edges 改用共享缓存,跨 chunk 复用同一 NodeIndex
  2. CREATE SEQUENCE 原位升级:命中推测节点时通过 graph[idx] 原位改写 explicit: true + location: Some(...),NodeIndex 不变、既有 UsesSequence 边自动指向升级后节点(petgraph 权重改写不改索引)
  3. 升级遵守精确 key 纪律(沿用本 PR 早前修复的跨 schema 语义):限定 DDL 只升级 full_key 推测节点、无前缀 DDL 只升级 short_key——CREATE SEQUENCE finance.seq_id 不会误升级 hr.seq_id 的推测节点
  4. dedup 兜底pick_richer_node 补 Sequence 臂(镜像 Table 的 location 风格),merge/dedup 优先保留带 DDL 位置的节点

测试(TDD Red→Green):3 个两 chunk 回归(仿 qualified_table_into_view_merged_then_bare_into_qualified 风格:引用→DDL 升级、双 chunk 引用共享单节点、跨 schema 不误升级)+ pick_richer_node_prefers_located_sequence。其中升级测试断言既有边存活(若误删重建即失败)。

已验证:cargo build/test/clippy --features full 全绿(686 passed, 0 failed);STORE_VERSION 未变(无序列化形状变更)。含历史双节点的旧构建产物可由 codeweb dedup(现在能正确保留 explicit 侧)清理。

残余歧义(记录不处理):chunk1 无前缀推测 seq_id + chunk2 限定 CREATE SEQUENCE finance.seq_id → key 不同不升级,双节点保留——无前缀引用在推测时刻 schema 本就未知,双节点是可辩护语义。

c2j added a commit that referenced this pull request Sep 8, 2026
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
c2j and others added 6 commits September 8, 2026 12:10
…sSequence 边

Node::Sequence 增加 explicit 标记与 Option<location>(对齐 Table/View 模式),推断节点由 builder 在 DDL 缺失时 or_insert 生成;schema 限定引用仅精确匹配 full key,不回退短名别名,避免跨 schema 误绑定。STORE_VERSION 8 -> 9。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
inferred_sequence_index 原为 create_object_ref_edges 局部缓存,跨 chunk(>100 SQL 文件)即失效:同一序列产生重复 seq* 节点,且后置 CREATE SEQUENCE 只查 sequence_index 造出兄弟 explicit 节点不升级。现提升为 GraphBuildContext 字段跨 chunk 共享;DDL 命中推测节点时原位改写 explicit/location(保留 NodeIndex 与既有边),升级遵守精确 key 纪律——限定 DDL 只升级限定推测节点,杜绝短名模糊匹配跨 schema 误绑定。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@c2j
c2j merged commit c7b880c into main Sep 8, 2026
2 checks passed
@c2j
c2j deleted the feat/issue-159 branch September 8, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 无 CREATE SEQUENCE 时为 seq.nextval 建 inferred seq* + UsesSequence(对齐 table*)

1 participant