database/gdb: 类型自动探测用 "int" 子串匹配,把 point/interval 等非整数类型判成整数
Author: lingcoderCreated Aug 11, 2026Updated Aug 11, 2026
问题
database/gdb/gdb_core_structure.go:360,驱动未显式列举的类型会落到 Core 的
自动探测分支,那里用子串匹配猜类型:
case strings.Contains(typeName, "int"):
if gstr.ContainsI(fieldType, "unsigned") {
return LocalTypeUint, nil
}
return LocalTypeInt, nil凡是类型名里含 int 的都被当成整数。PostgreSQL / openGauss 上至少这些不是
整数却会命中:
point(p-o-int)、interval、tinterval、int4range、int8range、
int4multirange、int8multirange,以及它们的数组形式。
后果是值被转成 0:
point 存 (1.5,2.5) 读回 0
interval 存 '2 days' 读回 0数据本身没问题,是读取时的类型判定错了。
佐证
- 该分支的匹配顺序是 text/char → float/double/numeric → bool → binary/blob →
int → time → date,所以
point会先命中int,走不到后面。 - 目前各驱动是靠在自己的
CheckLocalTypeForField里逐个列举来绕过它的。 pgsql 那份清单的 13 条 case 全是被报了 bug 之后才补的:bytea见 #4231 / #4677(由 #4678 修)、numeric[]/decimal[]见 #4457 (由 #4511 修)。 - #4840 又补进了
point/interval/ range 系列。
影响
清单式绕过只能挡住已经被发现的类型:任何未列举、名字里含 int 的类型仍会被
静默转成 0,而且每个驱动都要各自补一遍。
可能的修法
- 在 Core 里加一份「已知非整数」的排除清单;
- 或把子串匹配收紧(按词边界匹配,或改为精确类型名表)。
任一改法都会影响所有驱动,需要评估 dm / oracle / mssql / clickhouse 等本地 难以验证的驱动,所以先开 issue 记录,不直接改。
环境
- master (41baf1e28)
- 实测数据库:openGauss 7.0.0-RC1、PostgreSQL 17
Source: gogf/gf