Repository navigation
feat(sql): support multiline @set inline variable values (#7478) - #11147
Conversation
t8y2
left a comment
There was a problem hiding this comment.
感谢提交!多行 @set 值确实是 #7478 需要的能力,isNextDeclaration 的实现(跳过空白和注释后匹配 @set)本身写得很扎实,带 ; 的多行场景也验证正确。
但目前有一个必须先解决的回归:readValueEnd 去掉了「换行即终止值」的旧规则后,唯一剩下的终止条件是 ;、EOF、以及下一行是 @set。这意味着所有不带分号的既有写法都会被破坏,例如:
@set user_id = 42
select * from users where id = @user_id
旧版本会展开成完整查询;此 PR 下整个 select 被吞进变量值,随后 stripDeclaration 把它整段删除,最终 SQL 为空串(我在本地用 PR head 的文件实测确认,useSqlExecution.ts 中空 SQL 会静默取消执行,用户看不到任何报错)。带中间分号的变体会静默丢掉第一条语句;选中语句执行(declarationSql 路径)则产出重复且损坏的 SQL;值后行注释同理。这违反了仓库「Feature 不得破坏旧行为」的约定,且失败是静默的。
这个问题的难点在于:@set cond = from users\nwhere id = 42;(你新增测试期望的跨行续值)与 @set a = 42\nselect @a(旧行为应在新行终止)在词法上无法区分,需要一个产品层面的取舍,例如:多行值必须以 ; 结尾、只有从 = 下一行开始的值才允许多行、或其他明确的续行规则——任何选择都会与当前某个测试期望冲突,所以建议先在 Issue/PR 里讨论定下终止语义再改。DBeaver 的 @set 是严格单行的,没有可参考的先例。
另外两点小建议:补充 CRLF 用例(代码看起来已处理 \r 但无测试覆盖);补充「不带分号的声明后跟普通语句」的用例——这正是本次回归路径。期待调整后的版本。
…gle-line syntax (t8y2#7478)
|
非常感谢 @t8y2 的详尽评审和指引! 针对上述回归与语义取舍,本次采用了**选项 2(只有从 1. 语义规则与取舍说明
2. 具体改动
3. 验证结果
|
t8y2
left a comment
There was a problem hiding this comment.
感谢跟进,"只有从 = 下一行开始的值才允许多行"这个取舍很清晰,新 head(346b90f)已逐点复核:
- 无分号回归已修复:基础查询、中间分号多语句、值后行注释、declarationSql 选中执行四条路径均不再吞语句,并有单测与 useSqlExecution 端到端测试锁定;本地用新 head 的解析器实测这些场景及 CRLF 变体,行为全部符合预期。
- 终止语义已在
readDeclaration注释中明确文档化:多行值止于;、下一个@set或 EOF;同行起值保持单行语义,引号、美元引号、括号与 PG 数组跨行不受影响,@set出现在字符串/注释内不误判。 - CRLF 用例与"无分号声明后跟普通语句"用例均已补充,CI 全绿。
两点非阻塞备注,可后续跟进:多行值漏写终止 ; 且无后续 @set 时会吞到 EOF,最终 SQL 可能为空并静默取消(新语法的固有失败模式,建议后续加提示);单行值在括号内遇行注释时新版保留完整值(旧版会截断产生残缺 SQL),属修复性变化。LGTM。
|
Thanks for the contribution! Merged in 934d731, will be released in the next version. |
Summary
Resolves #7478.
Currently, inline SQL variables declared via
@setstop parsing at the first newline if the value is not enclosed within parentheses(...)or PostgreSQL array brackets[...]. As a result, multiline SQL fragments such as multilineFROM/WHEREclauses (@set cond =\n from users\n where id = 42;) only capture the line containing=or fail to recognize the variable altogether.Changes
readValueEndinapps/desktop/src/lib/sql/sqlVariables.tsto allow@setvariable values to span multiple lines until the terminating;.--) and block comments (/* ... */) within multiline values so comments (and any semicolons within comments) do not prematurely terminate the value.@setkeyword (isNextDeclaration) so unsemicoloned declarations preceding another@setdeclaration still terminate cleanly at newline.=or on new lines, inline comments, semicolons inside comments, and sequential multiline declarations.Verification
pnpm exec vitest run apps/desktop/src/lib/__tests__/sql/sqlVariables.spec.ts(28/28 passed)pnpm exec vitest run apps/desktop/src/lib/__tests__/sql/sqlVariableSyntax.spec.ts apps/desktop/src/composables/__tests__/useSqlExecution.spec.ts(89/89 passed)pnpm lint(0 errors)NODE_OPTIONS="--max-old-space-size=8192" pnpm typecheck(passed)