Skip to content

Fix:修复逗号分隔多表语句的别名补全#3441

Merged
t8y2 merged 5 commits into
t8y2:mainfrom
zipg:codex/comma-join-alias-completion
Jul 15, 2026
Merged

Fix:修复逗号分隔多表语句的别名补全#3441
t8y2 merged 5 commits into
t8y2:mainfrom
zipg:codex/comma-join-alias-completion

Conversation

@zipg

@zipg zipg commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

背景

SQL 语义模型此前对逗号分隔的多表语法只记录 FROM 后的第一张表,并且没有完整消费表引用的可选后缀或 joined-table 边界,导致后续表别名无法参与字段补全。

SELECT *
FROM generate_series(1, 3) WITH ORDINALITY AS g(value, ord),
     users u
     JOIN orders o ON o.user_id = u.id,
     audit_log a
WHERE a.

根因

parseRowSources 最初只解析每个 FROM / JOIN 引导词后紧邻的一个行源。后续增加同层逗号遍历后,仍存在以下不完整边界:

  • 别名 correlation column list 没有被完整消费
  • PostgreSQL 通用表函数和可选 LATERAL 没有统一进入函数行源解析
  • 表函数的 WITH ORDINALITY 会被当成普通别名
  • JOIN ... ON ... 后的同层逗号不再紧邻单个行源,无法由原循环继续解析

改动

  • 完整消费表、子查询和表函数别名后的 correlation column list
  • 将显式列别名写入语义行源,使 a(id)g(value) 可直接提供本地字段补全
  • PostgreSQL 方言支持带限定名的通用表函数及可选 LATERAL
  • 在解析函数别名前完整消费可选的 WITH ORDINALITY
  • 在 SELECT 顶层 FROM 子句范围内识别同层逗号,使完整 joined table 后的后续表也能进入语义模型
  • 增加模型与补全回归测试,覆盖连续三表、函数参数逗号、别名列清单、LATERALWITH ORDINALITY 和 joined-table 后逗号

安全性

  • 仅 PostgreSQL 方言放开通用函数识别,其他方言继续使用原有函数白名单
  • 明确排除 INSERT INTOUPDATEDELETE FROM 的写入目标,避免把插入列清单误判成函数调用
  • 增加 SQL Server FROM users (NOLOCK) 回归测试,避免表提示被误判为通用函数
  • 新的 joined-table 逗号识别仅作用于 SELECT 顶层 FROM 子句
  • 补齐 WINDOWQUALIFYFETCH 等后置子句边界,避免后续子句中的逗号产生伪表源
  • 函数参数和子查询内部逗号因 token 深度不同,不会被当成多表分隔符
  • 没有修改补全排序、元数据读取或 SQL 执行逻辑

验证

  • pnpm exec vitest run apps/desktop/src/lib/__tests__/sql/semantic/model.spec.ts apps/desktop/src/lib/__tests__/sql/semantic/completion.spec.ts:49/49 通过
  • pnpm check:format、lint、typecheck、test 全部通过

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Request changes: the comma-separated FROM parser still stops on valid row-source syntax.

  1. FROM table_a a(id), table_b b leaves the alias column list unconsumed, so the loop never reaches table_b; the same issue drops later tables in longer chains.

  2. Generic PostgreSQL table functions and LATERAL sources are parsed as ordinary table names because function-source detection only recognizes a fixed allowlist. For example, generate_series(...) g and LATERAL generate_series(...) g do not expose g for column completion.

Please make the parser consume a complete row source—including correlation column lists, generic function calls, and optional LATERAL—before looking for the next comma, and add regression tests for these cases.

@zipg

zipg commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

已按评审意见完成修改,提交:fb9162fb

  • 完整消费别名列清单,例如 table_a a(id)
  • PostgreSQL 支持通用表函数及可选 LATERAL
  • 完整解析当前行源后再继续处理同层逗号
  • 补充 correlation columns、通用函数、LATERAL 函数/子查询及后续表的回归测试
  • 限制通用函数识别范围并保护写入目标,同时增加 SQL Server NOLOCK 回归测试

验证结果:

  • 定向测试 44/44 通过
  • pnpm check 全部通过

@zipg
zipg requested a review from t8y2 July 14, 2026 11:42

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

request changes: 上次提到的基础 case 已经修复,但“完整消费当前行源后再处理逗号”仍有两个合法语法缺口。

  1. PostgreSQL 表函数的 WITH ORDINALITY 会被 aliasAfter 当成别名 with。例如 generate_series(...) WITH ORDINALITY AS g(value, ord), orders o 无法得到 g,也不会继续解析 orders。请完整消费可选的 WITH ORDINALITY 后再解析别名和 correlation columns。

  2. JOIN 后的逗号表源仍会丢失。例如 FROM users u JOIN orders o ON ..., audit_log a 只记录 usersorders,不会记录 audit_log。逗号分隔的是完整 table references,其中一个 reference 可以是 joined table;这里需要在完整 joined-table 边界之后继续处理同层逗号。

请补充这两个场景的模型与补全回归测试。

@zipg

zipg commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

已按本轮评审意见完成修改,提交:92a5084e

  • PostgreSQL 表函数会先完整消费可选的 WITH ORDINALITY,再解析别名和 correlation columns
  • SELECT 顶层 FROM 子句会在完整 joined table 后继续识别同层逗号表源
  • 补充两个场景的模型与实际字段补全回归测试
  • 额外补齐 WINDOW 等后置子句边界及回归测试,避免这些子句的逗号被误判为表源

验证结果:

  • 定向测试 49/49 通过
  • pnpm check 全部通过

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for the update. The previously reported WITH ORDINALITY and joined-table cases are fixed, but three compatibility issues remain.

  1. apps/desktop/src/lib/sql/semantic/model.ts treats every parenthesized token list after a table alias as correlation columns. In SQL Server, FROM users u (NOLOCK) is valid table-hint syntax, but the semantic model records NOLOCK as the table's only column and skips loading the real metadata. Please distinguish aliased SQL Server table hints and add a regression test.

  2. A partial PostgreSQL column alias list is treated as the complete source schema. For FROM users u(id), PostgreSQL only renames the first column; the remaining columns keep their original names. The current model prevents metadata loading, so all remaining columns disappear from completion. Please merge correlation names positionally with the underlying metadata and cover this through the completion path.

  3. LATERAL is consumed in every dialect. SQL Server permits an unquoted table named lateral, so FROM lateral l is currently parsed as a table named l with no alias. Please gate LATERAL handling by dialect and valid syntactic context.

@zipg

zipg commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

已按本轮评审意见完成修改,提交:08304be0

  • SQL Server 基础表后的 (NOLOCK) / WITH (NOLOCK) 作为 table hint 消费,不再误判为 correlation columns,并保留真实元数据列补全
  • PostgreSQL 基础表的 correlation aliases 与完整列清单分离;加载真实元数据后按位置覆盖已命名列,未命名的剩余列继续保留
  • LATERAL 仅在 PostgreSQL FROM / JOIN 且后续确实为函数或子查询时消费,SQL Server 中未加引号的 lateral 表名保持可用
  • 补充上述模型及实际字段补全回归测试

验证结果:

  • 定向测试 56/56 通过
  • pnpm check 全部通过
  • GitHub frontend CI 通过

@t8y2 本轮意见已处理完,烦请继续评审。

@zipg
zipg requested a review from t8y2 July 15, 2026 07:45
@t8y2
t8y2 force-pushed the codex/comma-join-alias-completion branch from 2521972 to 5105557 Compare July 15, 2026 09:30
@t8y2
t8y2 merged commit 1ab93a6 into t8y2:main Jul 15, 2026
7 checks passed
@t8y2

t8y2 commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Thanks for the contribution! Merged in 1ab93a6, will be released in the next version.

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.

2 participants