Reported issues for gaussdb-ro-mcp Desktop Extension
Pod holds 15 of 15 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.
Back to gaussdb-ro-mcp Desktop Extension.
Most discussed
tools: describe_table 各段错误处理不一致,constraints/indexes 失败被静默吞掉
问题描述
handleDescribeTable 对各段"尽力而为"查询的错误处理不一致:
DescribeColumns/ViewDefinition失败 → 输出columns_error/view_definition_error键 ✅TableComment、DescribeConstraints、DescribeIndexes、ListPartitions失败 → 键直接缺失,错误被静默吞掉 ❌
影响
pg_constraint / pg_index 查询失败(权限被回收、ctx 取消)时工具返回"成功",constraints/indexes 键缺失——LLM 无法区分"无约束/索引"与"查询失败",会把表当成无主键分析下去,没有任何错误信号可供纠正。
位置
internal/tools/tools.go:150-175
建议修复
统一为 []struct{name string; fn func(...)}…
Read the thread · 2026-09-10 · closed · 1 comment
db: detectPartitionSupport 出错也消耗 sync.Once,分区检测被永久错判
问题描述
detectPartitionSupport 用 sync.Once 缓存探测结果,但出错也会消耗 Once:瞬时错误(ctx 取消、连接抖动——agent 重试场景下很常见)把 partitionMode 永久钉死为 false,无重试、无日志。
影响
进程余生中所有分区表被错标为 table(GaussDB parttype='p' 检测失效),describe_table 静默缺失分区清单,且无从发现。
位置
internal/db/meta.go:38-49
建议修复
仅缓存成功结果:出错时不清 Once 的完成位(例如把 Once 换成 atomic.Bool + "已确定"标志,或 Once 内部 err 非 nil 时重置可重入的状态)。
Read the thread · 2026-09-10 · closed · 1 comment
db: 亚毫秒 statement_timeout 截断为 0,反而禁用服务端超时
问题描述
enforceReadOnly 用 stmtTimeout.Milliseconds()(整数毫秒)格式化 SET statement_timeout。亚毫秒的配置时长(如 yaml statement_timeout: 100us,合法解析为 100µs 且 >0 通过 SetDefaults)被截断为 0——在 PG/GaussDB 中语义是禁用超时,与配置意图完全相反(已实证)。
位置
internal/db/manager.go:103
建议修复
向下取整后为 0 时钳制为最小 1ms(max(1, ms)),或在 config 层校验 statement_timeout 不得小于 1ms 并报配置错误。
Read the thread · 2026-09-10 · closed · 1 comment
config: 未知 YAML 键被静默忽略,拼错的限制项实际在用默认值
问题描述
Load 使用不带 KnownFields 的 yaml.Unmarshal,未知/拼写错误的 YAML 键被静默忽略。
影响
server:
max_row: 5000 # max_rows 拼错
stmt_timeout: 10s # 拼错
加载零错误零日志,服务器以 max_rows=500、statement_timeout=30s 运行。运维以为设了紧约束,实际每个查询都在用默认语义——对一个以"限制"为核心卖点的工具尤其危险。
位置
internal/config/config.go:240
建议修复
改用 yaml.Decoder + dec.KnownFields(true) 拒绝未知键(注意 Duration 自定义 Unmarshal 兼容性);若担心破坏既有配置,至少对常见拼写在加载日志中告警。
Read the thread · 2026-09-10 · closed · 1 comment
config: blocked_functions 文档称前缀匹配、实现为精确匹配;非空配置会整体替换默认黑名单
问题描述
blocked_functions 的文档与实现不符,且替换语义未声明:
config.go:46注释与gaussdb-ro-mcp.example.yaml称"前缀匹配",但isBlockedFunction只对以*结尾的条目做前缀匹配,其余是剥通配后的精确匹配。按文档写pg_advisory期望前缀覆盖,实际只有精确名pg_advisory被拦,pg_try_advisory_lock等全部通过第 1 层。- schema 限定条目(如
pg_catalog.dblink)永远不匹配——比对只取尾段。 - 配置任何非空
blocked_functions会整体替换默认黑名单(dblink*、set_config、pg_read_file*…),追加一个pg_sleep会把其余全部放行,且无任何提示。
位置…
Read the thread · 2026-09-10 · closed · 1 comment
config: BuildDSN 不转义密码(含空格即损坏);ensureSSLMode 子串匹配可被密码抑制
问题描述
两个字面量拼接缺陷:
BuildDSN发出不加引号的keyword=value对。密码含空格(或引入歧义的字符)时产生损坏的 DSN:pass word@2026→password=pass word@2026 sslmode=disable,驱动解析器在空格处截断值、把word@2026当非法关键字 → "初始化实例失败"或密码错误(已实证)。ensureSSLMode用子串Contains("sslmode=")判断整个 DSN:密码中恰好含sslmode=(如xK3sslmode=9q)时,DSN 路径上预期的默认 sslmode 被抑制,驱动静默回退prefer。
位置
internal/config/config.go:163-180(BuildDSN)、config.go:207-224(ensureSSLMode)
建议修复
- 拆分字段路径:改用
url.URL+url.UserPassword构造 URL 形式…
Read the thread · 2026-09-10 · closed · 1 comment
tools: test_connection 在 transaction_read_only=off 时仍报 ok:true
问题描述
test_connection 在 SHOW transaction_read_only 查询成功时即报 "ok": true,即使查询返回的是 off。一个以"只读状态检查"为卖点的工具,对恰好是 enforceReadOnly 要抓的故障形态(启动参数被代理剥离、会话可写)亮绿灯。
复现
对启动参数被剥离、会话实际可写的池调用 test_connection:
{"ok": true, "transaction_read_only": "off"}
位置
internal/tools/tools.go:92("ok": roErr == nil)
建议修复
ok 应要求 strings.EqualFold(ro, "on"),与 enforceReadOnly 的判定一致;off 时可附 read_only_check_error: "transaction_read_only=off" 之类的显式错误信息。
Read the thread · 2026-09-10 · closed · 1 comment
db: Select/Query 行 map 按列名建键,重复列名静默丢数据
问题描述
Instance.Select(及 Query)的行映射以输出列名为 map 键:重复列名时第 N 列的值静默覆盖第 1 列的值,Columns(长度 N)与行 map(键更少)不一致。
复现
SELECT u.id, o.id FROM users u JOIN orders o ON u.id = o.user_id
返回 columns: ["id","id"],但每行 map 只剩一个 id 键(持有第二个 id)——第一列数据静默丢失,且 truncated: false、row_count 正常,消费结果的 agent 无法察觉丢失。
位置
internal/db/manager.go:204-215(Select 行循环)、manager.go:236-248(Query 同样问题)
建议修复
任选其一:
- 行结构改为
[]any按位置对应columns(破坏现有 map 形态,需评估客户端兼容); - 保留 map…
Read the thread · 2026-09-10 · closed · 1 comment
Most recent
db: newInstance 无条件覆盖 ConnectTimeout,实例级 connect_timeout 配置失效
问题描述
newInstance 在 gaussdbxpool.ParseConfig 之后无条件用服务级值覆盖 poolCfg.ConnConfig.ConnectTimeout,静默丢弃用户通过 DSN 或 options 传入的实例级 connect_timeout——而 config.go:65 的注释明确把 connect_timeout=5 列为受支持的 Options 条目(驱动确实会解析它,见 vendored gaussdbconn/config.go:281-287)。
影响
instances:
- name: slow-endpoint
options: ["connect_timeout=1"] # 期望 1s
# server.connect_timeout 未设置 → 默认 10s
连接黑洞时尝试会停滞约 10s 而非配置的 1s,且无任何提示。
位置
internal/db/manager.go:74
建议修复
仅当实例/DSN…
Read the thread · 2026-09-10 · closed · 1 comment
config: instances 列表含空项时 SetDefaults 解引用 nil 而 panic
问题描述
YAML 中 instances: 列表的空列表项解码为 nil *Instance 指针,而 Load 的调用顺序是先 SetDefaults() 再 validate()——SetDefaults 在 inst.SSLMode == ""(config.go:110)处对 nil 解引用,直接 panic。
复现(已实证)
instances:
-
- name: ok
config.Load 以 runtime error: invalid memory address or nil pointer dereference panic(stderr 带堆栈),而不是走文档化的"配置加载失败"错误路径。
位置
internal/config/config.go:108-124(SetDefaults 的实例循环)与 config.go:241-245(Load 中 SetDefaults 先于 validate)
建议修复
任选其一: 1.…
Read the thread · 2026-09-10 · closed · 1 comment
main: SIGINT/SIGTERM 优雅退出被当作崩溃(退出码 1)
问题描述
SIGINT/SIGTERM 触发 signal.NotifyContext 取消后,MCP SDK 的 Server.Run 返回 ctx.Err()(context.Canceled,见 vendor 内 mcp/server.go:1295-1303)。而 main 中 start 返回的任何非空错误都走 logger.Fatalf → os.Exit(1)。
结果:每次正常关闭都被记录为崩溃——日志打出 gaussdb-ro-mcp 退出: context canceled,退出码 1。与第 55 行"优雅退出"注释矛盾;systemd Restart=on-failure 会重启循环,MCP 客户端会把服务器记为异常退出。
复现
启动 stdio 服务器 → 发送 SIGTERM(或客户端关闭 agent 时的常规信号)→ 观察退出码 1 与 fatal 日志。
位置
cmd/gaussdb-ro-mcp/main.go:70(start 返回 server.Run…
Read the thread · 2026-09-10 · closed · 1 comment
[安全] db: enforceReadOnly 中 SET statement_timeout 先于 ROLLBACK,破坏只读回退路径且可致连接无超时入池
问题描述
enforceReadOnly 的执行顺序是:先 SET statement_timeout,再回读校验只读,失败才 ROLLBACK + 会话级 SET READ ONLY 回退。这个顺序破坏了注释(manager.go:113-118)所描述的恢复路径:
- 场景 a(中止的残留事务):
SET本身失败(SQLSTATE 25P02),函数提前返回错误——注释里的ROLLBACK回退永远执行不到,连接被拒绝,且报错信息误导性地显示"设置 statement_timeout 失败"。 - 场景 b(打开的残留事务):
SET成功但属事务作用域,随后的ROLLBACK(回退路径的一部分)把它回滚掉了且从未重设——连接带着无服务端超时的状态入池,长查询只剩客户端 ctx 一条边界。
位置
internal/db/manager.go:101-129(第 103 行 SET 与第 117 行 ROLLBACK 的顺序)
建议修复
调整顺序:回读校验失败 → 先…
Read the thread · 2026-09-10 · closed · 1 comment
[安全] guard: 咨询锁黑名单枚举了不存在的函数名,遗漏 pg_try_advisory_* 系列(可致持久 DoS)
问题描述
defaultBlockedFunctions 中咨询锁一节枚举了三个不存在的函数名:
pg_advisory_share_lock(不存在)pg_advisory_share_lock_shared(不存在)pg_advisory_xact_share_lock(不存在)
同时遗漏了真实的:
pg_try_advisory_lock、pg_try_advisory_xact_lockpg_advisory_lock_shared、pg_advisory_xact_lock_shared、pg_try_advisory_xact_lock_sharedpg_try_advisory_lock_shared
而 README 和 gaussdb-ro-mcp.example.yaml 均声称 pg_advisory_* 默认被拦截。
影响
咨询锁在只读事务中是允许的,第 2 层会话只读无法兜底:
SELECT…
[Read the thread](https://github.com/gxc/gaussdb-ro-mcp/issues/3) · 2026-09-10 · closed · 1 comment
### [安全] guard: 引号标识符函数名("dblink"(...) 等)完全绕过危险函数黑名单
## 问题描述
`tokenize` 给引号标识符 token 加了 `\x00` 前缀(`guard.go:241`),使其不参与关键字匹配;但危险函数黑名单检查以 `isWordToken(t)` 为门槛(`guard.go:86`),而 `isWordToken` 拒绝以 `\x00` 开头的 token——于是**用引号包裹函数名即可完全绕过黑名单**:
```sql
SELECT "dblink"('host=10.0.0.1 dbname=x', 'insert into t values(1)') -- 通过
SELECT "set_config"('statement_timeout','0',false) -- 通过
SELECT pg_catalog."pg_read_file"('postgresql.conf',0,100) -- 通过
SELECT "nextval"('s') -- 通过…
[Read the thread](https://github.com/gxc/gaussdb-ro-mcp/issues/2) · 2026-09-10 · closed · 1 comment
### [安全] guard: E''/U&'' 反斜杠判定忽略邻接关系,字符串边界反转可隐藏 set_config/dblink 调用
## 问题描述
`internal/guard/guard.go` 的 `tokenize` 在处理字符串字面量时,通过检查**前一个 token 是否为 `e`/`u`** 来决定是否启用反斜杠转义(E''/U&'' 语法),但忽略了邻接关系:即使 `e`/`u` 只是一个普通的列名/别名 token(与后面的字符串之间隔着逗号等标点),也会让后续字符串按转义语法 lex。
这会**反转 guard 与服务端之间的字符串边界认定**:
- **绕过方向**:guard 认为 `'\'` 是转义字符串的一部分,把紧随其后的 `set_config(...)`、`dblink(...)` 等吞进字符串;而服务端(`standard_conforming_strings=on`)认为 `'\'` 是完整字符串,危险函数真实执行。
- **误拒方向**:合法 SQL `SELECT e, '\' FROM t`(`e` 是列名)被误报"SQL 存在未闭合的字符串字面量"。
## 复现(已实证)
```sql
SELECT e, '\',…
[Read the thread](https://github.com/gxc/gaussdb-ro-mcp/issues/1) · 2026-09-10 · closed · 1 comment
The remaining reports are on [the project's issue tracker](https://github.com/gxc/gaussdb-ro-mcp/issues).