--- name: 修复达梦数据库越界和引号 overview: 修复 HoTime 框架代码生成器的两个达梦(DM)数据库问题:(1) 获取表列表时越界包含了系统表;(2) SQL 查询使用了 MySQL 反引号语法导致达梦解析失败。 todos: - id: fix-dm-table-filter content: 修改 code/makecode.go 的达梦表列表和列信息查询,使用 ALL_TAB_COMMENTS + OWNER 过滤 status: completed - id: fix-backtick-convert content: 修改 db/identifier.go 的 ProcessFieldList,增加 convertQuotes 调用转换残留反引号 status: completed - id: regen-admin-json content: 删除/清理 myst-go/config/admin.json 中的系统表条目,重新生成配置 status: completed isProject: false --- # 修复达梦数据库越界获取系统表和反引号语法错误 ## 问题分析 ### 问题 1:越界获取非 ZWBG 数据库的表 [code/makecode.go](d:\work\hotimev1.5\code\makecode.go) 第 121-122 行: ```go nowTables = db.Query(`SELECT TABLE_NAME AS "name", COMMENTS AS "label" FROM USER_TAB_COMMENTS WHERE TABLE_TYPE='TABLE'`) ``` 使用 `SYSDBA` 用户连接达梦时,`USER_TAB_COMMENTS` 返回该用户下**所有表**,包括达梦系统表(`SYSJOBS`、`SYSJOBSCHEDULES`、`SYSALERTS`、`##HISTOGRAMS_TABLE` 等),导致 [admin.json](d:\work\myst-go\config\admin.json) 中混入了大量不属于 ZWBG 业务的系统表。 同样的问题存在于第 169-170 行的列信息查询(`USER_TAB_COLUMNS` / `USER_COL_COMMENTS`)。 ### 问题 2:反引号导致 SQL 语法错误(遗留问题) `makecode.go` 中 `Info`(第 725 行)和 `Search`(第 958 行)使用反引号拼接列名字符串:``col1`,`col2`,...`。 `crud.go` 的 `Select` 方法有**两种字段处理路径**: - **Slice 路径**(第 100-109 行):每个列名走 `ProcessColumnNoPrefix` -> `QuoteIdentifier`,能正确转换引号 - **String 路径**(第 93-99 行):整个字符串走 `ProcessFieldList` -> `ProcessConditionString`,三个正则都只匹配 `table.column` 格式(含 `.`),不处理单独的反引号列名 `makecode.go` 传的是拼接好的**字符串**,走的是 String 路径,所以反引号不会被自动转换,导致达梦报语法错误。 --- ## 修复方案 ### 修改 1:过滤达梦系统表 - [code/makecode.go](d:\work\hotimev1.5\code\makecode.go) 将 `USER_TAB_COMMENTS` / `USER_TAB_COLUMNS` 改为 `ALL_TAB_COMMENTS` / `ALL_TAB_COLUMNS`,并通过 `OWNER` 过滤为 `db.DBName`(即 `ZWBG`),确保只获取目标 schema 的业务表。 **第 121-122 行**,表列表查询改为: ```go 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 行**,列信息查询改为: ```go 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](d:\work\hotimev1.5\db\identifier.go) `makecode.go` 的反引号属于遗留代码,理论上 `Select` 的 Slice 路径已能自动处理引号,但 `makecode.go` 传的是字符串。最小改动:在 `ProcessFieldList` 末尾加 `convertQuotes` 调用,将 `ProcessConditionString` 未能匹配到的残留反引号统一转为当前方言引号: ```go 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](d:\work\myst-go\config\admin.json) 代码修复后,需要删除当前 `admin.json`(已包含系统表污染)并重启应用让其自动重新生成。需要注意的是: - 如果 `admin.json` 中有手工定制的菜单/权限配置,**需先备份**再删除 - 或者手动从 `admin.json` 中删除以下系统表条目:`SYSJOBSCHEDULES`、`SYSJOBSTEPS`、`SYSJOBHISTORIES`、`SYSJOBHISTORIES2`、`SYSSTEPHISTORIES2`、`SYSALERTHISTORIES`、`SYSALERTNOTIFICATIONS`、`SYSALERTS`、`SYSMAILINFO`、`SYSOPERATORS`、`SYSJOBS`、`##HISTOGRAMS_TABLE`、`cached`、`hotime_cache`、`test_batch` --- ## 数据流概览 ```mermaid 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 ```