OpenGauss内置函数初始化与查询全解析
1. initdb 时写入 pg_proc 的代码builtin_funcs.ini 不是运行时读取的文本文件而是通过 #include 在编译时被预处理器内联到 C 源码中src/common/backend/catalog/pg_builtin_proc.cpp生成 FuncGroup g_func_groups[] 数组。 t写入 pg_proc 的核心代码在 src/common/backend/utils/cache/catcache.cpp- InsertBuiltinFuncInBootstrap()约第 2495 行遍历 g_func_groups[]对每个 Builtin_func 调用 CreateHeapTuple4BuiltinFunc() 构建 HeapTuple然后通过simple_heap_insert() 直接插入到 bootstrap 模式的 pg_proc 关系描述符中。- 这个函数在 src/gausskernel/bootstrap/bootparse.y 中当创建 pg_proc 关系后被调用约第 250 行。- CreateHeapTuple4BuiltinFunc()约第 1834 行负责将 Builtin_func 结构体的各个字段参数类型、返回值、语言ID、权限等组装成符合 pg_proc 系统表布局的HeapTuple。2. 查询时是否直接使用全局变量查询时有两条路径快速路径按 OID 查找—— 直接用全局变量跳过 pg_proc 表- fmgr.cpp 中的 fmgr_isbuiltin() 调用 SearchBuiltinFuncByOid()从 oidHash 哈希表中直接查到 Builtin_func 指针- 如果命中fmgr_info_cxt_security() 直接将 fn_addr 指向 C 函数地址不查询 pg_proc 物理表慢速路径按名称参数查找—— 缓存未命中时用全局变量动态构造- 当系统缓存 SearchSysCache1(PROCNAMEARGSNSP, ...) 未命中时SearchCatCacheListMiss() 会调用 SearchBuiltinProcCacheList()- 该函数通过 nameHash 哈希表找到匹配的 Builtin_func再用 CreateHeapTuple4BuiltinFunc() 动态构建一个 HeapTuple 返回- 注意这里构建的 HeapTuple 和 bootstrap 阶段 simple_heap_insert 写入磁盘的物理 pg_proc 数据是共存的整体流程builtin_funcs.ini└─ #include 编译时内联 ─► g_func_groups[] / nameHash / oidHash│├─ initBuiltinFuncs() 进程启动时初始化哈希表│├─ Bootstrap 阶段 ─► InsertBuiltinFuncInBootstrap() ─► simple_heap_insert(pg_proc)│└─ 查询阶段├─ fmgr_isbuiltin(oid) ─► oidHash 直接查 ─► 返回 fn_addr不走 pg_proc 表└─ 按名缓存未命中 ─► nameHash 查 ─► CreateHeapTuple4BuiltinFunc() 动态构造 Tuple