Files
hotime/.cursor/plans/修复达梦数据库越界和引号_eafbbf76.plan.md
T
hoteas 3681564ca4 feat(config): 扩展数据类型映射与数据库字段备注提取功能
- 在 ColumnDataType 中新增对 PostgreSQL 和 Oracle 数据类型的支持
- 更新 Db2JSON 方法,优化对达梦数据库表和列信息的查询逻辑
- 增强字段备注解析,支持从备注中提取提示信息并清理标签
- 更新文档,详细说明字段备注格式及前端提示的展示效果
2026-03-23 16:48:56 +08:00

5.4 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
修复达梦数据库越界和引号 修复 HoTime 框架代码生成器的两个达梦(DM)数据库问题:(1) 获取表列表时越界包含了系统表;(2) SQL 查询使用了 MySQL 反引号语法导致达梦解析失败。
id content status
fix-dm-table-filter 修改 code/makecode.go 的达梦表列表和列信息查询,使用 ALL_TAB_COMMENTS + OWNER 过滤 completed
id content status
fix-backtick-convert 修改 db/identifier.go 的 ProcessFieldList,增加 convertQuotes 调用转换残留反引号 completed
id content status
regen-admin-json 删除/清理 myst-go/config/admin.json 中的系统表条目,重新生成配置 completed
false

修复达梦数据库越界获取系统表和反引号语法错误

问题分析

问题 1:越界获取非 ZWBG 数据库的表

code/makecode.go 第 121-122 行:

nowTables = db.Query(`SELECT TABLE_NAME AS "name", COMMENTS AS "label" FROM USER_TAB_COMMENTS WHERE TABLE_TYPE='TABLE'`)

使用 SYSDBA 用户连接达梦时,USER_TAB_COMMENTS 返回该用户下所有表,包括达梦系统表(SYSJOBSSYSJOBSCHEDULESSYSALERTS##HISTOGRAMS_TABLE 等),导致 admin.json 中混入了大量不属于 ZWBG 业务的系统表。

同样的问题存在于第 169-170 行的列信息查询(USER_TAB_COLUMNS / USER_COL_COMMENTS)。

问题 2:反引号导致 SQL 语法错误(遗留问题)

makecode.goInfo(第 725 行)和 Search(第 958 行)使用反引号拼接列名字符串:``col1,col2,...

crud.goSelect 方法有两种字段处理路径

  • Slice 路径(第 100-109 行):每个列名走 ProcessColumnNoPrefix -> QuoteIdentifier,能正确转换引号
  • String 路径(第 93-99 行):整个字符串走 ProcessFieldList -> ProcessConditionString,三个正则都只匹配 table.column 格式(含 .),不处理单独的反引号列名

makecode.go 传的是拼接好的字符串,走的是 String 路径,所以反引号不会被自动转换,导致达梦报语法错误。


修复方案

修改 1:过滤达梦系统表 - code/makecode.go

USER_TAB_COMMENTS / USER_TAB_COLUMNS 改为 ALL_TAB_COMMENTS / ALL_TAB_COLUMNS,并通过 OWNER 过滤为 db.DBName(即 ZWBG),确保只获取目标 schema 的业务表。

第 121-122 行,表列表查询改为:

if db.Type == "dm" || db.Type == "dameng" {
    nowTables = db.Query(`SELECT TABLE_NAME AS "name", COMMENTS AS "label" FROM ALL_TAB_COMMENTS WHERE TABLE_TYPE='TABLE' AND OWNER='` + strings.ToUpper(db.DBName) + `'`)
}

第 169-170 行,列信息查询改为:

if db.Type == "dm" || db.Type == "dameng" {
    tableInfo = db.Query(`SELECT c.COLUMN_NAME AS "name", c.DATA_TYPE AS "type", m.COMMENTS AS "label", c.NULLABLE AS "must", c.DATA_DEFAULT AS "dflt_value" FROM ALL_TAB_COLUMNS c LEFT JOIN ALL_COL_COMMENTS m ON c.TABLE_NAME=m.TABLE_NAME AND c.COLUMN_NAME=m.COLUMN_NAME AND c.OWNER=m.OWNER WHERE c.TABLE_NAME='` + v.GetString("name") + `' AND c.OWNER='` + strings.ToUpper(db.DBName) + `' ORDER BY c.COLUMN_ID`)
}

修改 2:修复反引号转换 - db/identifier.go

makecode.go 的反引号属于遗留代码,理论上 Select 的 Slice 路径已能自动处理引号,但 makecode.go 传的是字符串。最小改动:在 ProcessFieldList 末尾加 convertQuotes 调用,将 ProcessConditionString 未能匹配到的残留反引号统一转为当前方言引号:

func (p *IdentifierProcessor) ProcessFieldList(fields string) string {
    if fields == "" || fields == "*" {
        return fields
    }
    result := p.ProcessConditionString(fields)
    result = p.convertQuotes(result)
    return result
}

convertQuotes(第 240-248 行)已实现引号转换:达梦将反引号转为 "MySQL 保持不变(no-op)。这样无需修改 makecode.go 中的遗留反引号代码,所有走 ProcessFieldList 的字符串都能被正确处理。

修改 3:重新生成 admin.json - config/admin.json

代码修复后,需要删除当前 admin.json(已包含系统表污染)并重启应用让其自动重新生成。需要注意的是:

  • 如果 admin.json 中有手工定制的菜单/权限配置,需先备份再删除
  • 或者手动从 admin.json 中删除以下系统表条目:SYSJOBSCHEDULESSYSJOBSTEPSSYSJOBHISTORIESSYSJOBHISTORIES2SYSSTEPHISTORIES2SYSALERTHISTORIESSYSALERTNOTIFICATIONSSYSALERTSSYSMAILINFOSYSOPERATORSSYSJOBS##HISTOGRAMS_TABLEcachedhotime_cachetest_batch

数据流概览

flowchart LR
    subgraph code_gen [代码生成 - makecode.go]
        A["Db2JSON()"] -->|"USER_TAB_COMMENTS (修复前)"| B["获取所有表含系统表"]
        A -->|"ALL_TAB_COMMENTS + OWNER (修复后)"| C["仅获取ZWBG业务表"]
    end
    subgraph query [查询执行 - code.go + crud.go]
        D["Info/Search 拼字段"] -->|反引号列名| E["ProcessFieldList"]
        E -->|"ProcessConditionString (不匹配)"| F["反引号保留 -> DM报错"]
        E -->|"+ convertQuotes (修复后)"| G["转为双引号 -> DM正常"]
    end