🐛 fix(oracle): 修复 Oracle/Dameng 打开表时缺少 schema 前缀导致 ORA-00942

- 问题根因:GetTables 在 dbName 为空时走 user_tables 分支返回纯表名,下游 SQL 缺少 owner 前缀,引用未授权 schema 的表时报 ORA-00942
- SQL 修复:user_tables 分支改用 USER 伪列拼接 owner,确保始终返回 OWNER.TABLE_NAME 格式
- 驱动兼容:列别名用双引号包裹强制大写(AS "OWNER" / AS "TABLE_NAME"),避免不同驱动返回不一致 case 导致 row map 取值失败
- 边界保护:增加 TABLE_NAME 为 NULL 的跳过逻辑,避免污染表名输出
- 达梦对齐:DamengDB.GetTables 同步修复,保持与 Oracle 实现一致
- 测试覆盖:新增 3 个回归用例(all_tables 路径、user_tables 路径、NULL 值跳过),扩展 recording driver 支持 mock 任意查询结果
Refs #445
This commit is contained in:
Syngnat
2026-05-11 19:46:24 +08:00
parent 2d9d5f0e98
commit b22d28b79c
6 changed files with 138 additions and 163 deletions

View File

@@ -28,6 +28,12 @@ type oracleRecordingState struct {
execQueries []string
execArgs [][]driver.NamedValue
rowsAffected int64
queryResults map[string]oracleRecordingQueryResult
}
type oracleRecordingQueryResult struct {
columns []string
rows [][]driver.Value
}
func (s *oracleRecordingState) snapshotExecQueries() []string {
@@ -80,6 +86,16 @@ func (c *oracleRecordingConn) ExecContext(_ context.Context, query string, args
}
func (c *oracleRecordingConn) QueryContext(_ context.Context, query string, _ []driver.NamedValue) (driver.Rows, error) {
c.state.mu.Lock()
if result, ok := c.state.queryResults[query]; ok {
c.state.mu.Unlock()
return &oracleRecordingRows{
columns: append([]string(nil), result.columns...),
rows: cloneOracleRecordingRows(result.rows),
}, nil
}
c.state.mu.Unlock()
if strings.Contains(strings.ToLower(query), "tab_columns") {
return &oracleRecordingRows{
columns: []string{"COLUMN_NAME", "DATA_TYPE", "NULLABLE", "DATA_DEFAULT"},
@@ -92,6 +108,14 @@ func (c *oracleRecordingConn) QueryContext(_ context.Context, query string, _ []
return &oracleRecordingRows{}, nil
}
func cloneOracleRecordingRows(src [][]driver.Value) [][]driver.Value {
dst := make([][]driver.Value, len(src))
for i, row := range src {
dst[i] = append([]driver.Value(nil), row...)
}
return dst
}
var _ driver.ExecerContext = (*oracleRecordingConn)(nil)
var _ driver.QueryerContext = (*oracleRecordingConn)(nil)
@@ -135,7 +159,7 @@ func openOracleRecordingDB(t *testing.T) (*sql.DB, *oracleRecordingState) {
oracleRecordingDriverMu.Lock()
oracleRecordingDriverSeq++
dsn := fmt.Sprintf("oracle-recording-%d", oracleRecordingDriverSeq)
state := &oracleRecordingState{rowsAffected: 1}
state := &oracleRecordingState{rowsAffected: 1, queryResults: map[string]oracleRecordingQueryResult{}}
oracleRecordingDriverStates[dsn] = state
oracleRecordingDriverMu.Unlock()