Skip to content

feature(gaussdb): 支持带 psql 控制命令的匿名块执行 - #7100

Merged
t8y2 merged 4 commits into
mainfrom
codex/issue-6468-opengauss-script
Aug 26, 2026
Merged

feature(gaussdb): 支持带 psql 控制命令的匿名块执行#7100
t8y2 merged 4 commits into
mainfrom
codex/issue-6468-opengauss-script

Conversation

@zipg

@zipg zipg commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

改动

  • GaussDB/openGauss 执行脚本时忽略可安全映射的 gsql 控制命令:\\set ON_ERROR_STOP on\\set VERBOSITY ...\\timing
  • 控制命令仅从发送给数据库的 SQL 中移除,不再提交尚未结束的 query buffer
  • ON_ERROR_STOP on 传入执行计划,即使请求设置 continueOnError=true 也会在首个错误后停止
  • 按完整变量名和合法值解析;普通 \\set、相似变量名及 ON_ERROR_STOP off 均不会被静默忽略
  • 保持完整执行、光标执行和流式 SQL 文件分割行为一致

验证

  • 修复前:issue 同结构脚本被拆为 7 条,真实 openGauss 5.0.0 首条报 syntax error at or near "\\"
  • 修复后:真实 openGauss 5.0.0 匿名块只产生 1 个结果并返回预期 NOTICE
  • 真实 openGauss:SELECT / \\timing / 1 保持为一条语句并返回 1
  • 真实 openGauss:请求显式设置 continueOnError=true,首条缺表后仅返回 1 个错误结果,后续建表未执行
  • cargo test -p dbx-core --lib sql::tests:::1008 通过,3 忽略
  • cargo test -p dbx-core --lib sql::tests::gaussdb_:25 通过
  • cargo test -p dbx-core --lib query::tests::gaussdb_on_error_stop_overrides_continue_on_error:通过
  • cargo fmt -p dbx-core -- --check
  • git diff --check

Closes #6468

@github-actions github-actions Bot added area/core Shared DBX core runtime bug Something isn't working labels Aug 24, 2026
@zipg zipg changed the title fix(gaussdb): 支持带 psql 控制命令的匿名块执行 feature(gaussdb): 支持带 psql 控制命令的匿名块执行 Aug 25, 2026
@github-actions github-actions Bot removed the bug Something isn't working label Aug 25, 2026

@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.

当前精确 head 92fd9f06df1338c5dc828d9058f2c06d87c173fb 还有三处脚本语义问题,需要作者侧统一修正:

  1. crates/dbx-core/src/sql.rs:513 / :894 遇到 \\set 等控制命令时会无条件提交尚未结束的 SQL 缓冲区。psql/gsql 的反斜杠命令由客户端处理,并且部分命令作用于“当前 query buffer”;控制命令本身不等价于 SQL 终止符。请保留未完成缓冲区,只有明确执行缓冲区的命令才提交。PostgreSQL 官方说明:https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-META-COMMANDS

  2. crates/dbx-core/src/sql.rs:1483 识别到 ON_ERROR_STOP 后直接丢弃,但执行器仍可能在前一条 SQL 失败后继续执行后续语句。这会把原脚本的失败控制语义静默改掉。openGauss 官方说明 \\set ON_ERROR_STOP on 应在错误时立即停止脚本:https://docs.opengauss.org/en/docs/6.0.0/docs/ToolandCommandReference/gsql.html

  3. crates/dbx-core/src/sql.rs:1482 对控制变量的匹配过宽,包含 ON_ERROR_STOP 文本的其他变量名也可能被误判。请按完整变量名和合法值解析,并补充“未完成 SQL + 控制命令”“ON_ERROR_STOP 停止执行”“相似变量名不误判”的回归测试。

这些问题共同涉及解析器与执行器之间的控制流契约,不适合只做局部 maintainer patch。

@zipg

zipg commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

已按审核意见统一修正解析器与执行器的控制流契约:

  1. gsql 控制命令只从 SQL 中移除,不再提交或清空未完成的 query buffer。
  2. \\set ON_ERROR_STOP on 会写入执行计划,并覆盖请求中的 continueOnError=true
  3. 控制变量按完整名称和合法值匹配,补充了未完成 SQL、停止执行、相似变量名不误判的回归测试。

已在真实 openGauss 5.0.0 验证:控制命令位于未完成 SELECT 中间仍返回 1;首条 SQL 失败时后续建表未执行。

@zipg
zipg requested a review from t8y2 August 25, 2026 05:44

@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.

当前精确 head 18a834eb34cc7f1e22d9394b57e5b6d85515462e 已修复上一轮的三个普通执行问题,但流式 SQL 文件导入仍未保持 ON_ERROR_STOP 语义:

  • SqlStatementSplitter 在识别 \\set ON_ERROR_STOP on 后只把状态写入 stop_on_errorcrates/dbx-core/src/sql.rs:513:579)。
  • SQL 文件路径通过 StreamingSqlFileSplitter 仅取出 statements;finish(self) 直接消费 splitter,整个 sql_file_import.rs 没有读取或传播该状态(crates/dbx-core/src/sql_file_import.rs:422:641-668)。
  • 导入语句失败时仍直接使用 request.continue_on_error:1204-1208:1295-1300),所以请求开启继续执行时,文件中的 \\set ON_ERROR_STOP on 虽被静默移除,后续错误仍会继续执行下一条 SQL。

因此,一个 SQL 文件包含 \\set ON_ERROR_STOP on、一条必失败 SQL、再跟一条有副作用 SQL,同时请求 continueOnError=true,仍可能执行最后一条;这与 PR 描述中的“保持流式 SQL 文件分割行为一致”不符,也违反 gsql 的错误即停语义:https://docs.opengauss.org/en/docs/6.0.0/docs/ToolandCommandReference/gsql.html

请把控制状态按脚本位置传播到流式导入执行器(注意不要仅在 EOF 读取最终布尔值而错误影响控制命令之前的语句),并补一条走 sql_file_import 执行/错误决策路径的回归测试,证明上述文件在 continueOnError=true 时不会执行失败语句后的 SQL。

@zipg

zipg commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

已处理本轮流式 SQL 文件导入审核意见:

  • SqlStatementSplitter 现在按每条语句产生时的位置携带 ON_ERROR_STOP 状态,未使用 EOF 最终状态回填前序语句
  • 流式与内存 SQL 文件导入都会将该状态传播到执行/错误决策路径;continueOnError=true 时,控制命令后的错误仍会立即停止
  • SQL 文件导入优化仅合并控制状态相同的连续语句,合并 INSERT 的回退执行也保持相同语义
  • 新增回归测试覆盖:控制命令前的失败允许继续并产生 1 条副作用,控制命令后的失败立即停止,末尾副作用不执行

验证:

  • cargo test -p dbx-core --lib(5446 passed,60 ignored)
  • cargo clippy -p dbx-core --lib -- -D warnings -A clippy::nonminimal_bool
  • cargo fmt -p dbx-core
  • git diff --check

@t8y2
t8y2 merged commit 68eae4a into main Aug 26, 2026
14 checks passed
@t8y2

t8y2 commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Thanks for the contribution! Merged in 68eae4a, 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

area/core Shared DBX core runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 无法执行函数与存储过程的sql界面执行

2 participants