You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL创建自引用复合类型报错的解决方法

当执行以下自引用复合类型创建代码时,PostgreSQL会抛出composite type t_mytype cannot be made a member of itself错误:

CREATE TYPE t_mytype AS ( id uuid );
ALTER TYPE t_mytype ADD ATTRIBUTE children t_mytype[];

该限制来自PostgreSQL的内置类型校验逻辑:复合类型创建阶段需要计算固定的内存布局,直接持有自身类型的成员会触发无限递归的长度计算,因此被默认拦截。针对仅在PL/pgSQL函数内作为入参、做递归结构遍历、不做持久化存储的场景,可以通过以下方案绕过限制。

可行实现方案

使用DOMAIN作为中间代理层穿透自引用校验,该方案完全保留类型安全,使用体验和原生自引用数组无差异:

-- 1. 创建基础复合类型
CREATE TYPE t_mytype AS ( id uuid );
-- 2. 定义DOMAIN作为t_mytype数组的代理别名,该步骤可正常执行,因t_mytype已完成定义
CREATE DOMAIN d_mytype_children AS t_mytype[];
-- 3. 为复合类型添加子节点属性,使用DOMAIN类型绕开直接自引用检查
ALTER TYPE t_mytype ADD ATTRIBUTE children d_mytype_children;

使用说明

  • 上述方式定义的类型在PL/pgSQL逻辑中使用时,children属性的操作逻辑和直接定义为t_mytype[]完全一致,支持数组遍历、递归访问、成员取值等所有常规操作,无需额外做类型转换。
  • 该方案仅适配内存中的函数计算场景,不要使用该复合类型创建数据表、存储持久化数据,否则会触发TOAST存储、数据写入阶段的递归处理异常。
  • 如果不需要强类型校验,也可以直接将children属性定义为anyarray类型,递归处理时在函数内部手动强转为t_mytype[]即可,无需创建额外DOMAIN,但该方式无编译期类型检查,容错性更低。

内容的提问来源于stack exchange,提问作者Dewey Vozel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:27:35