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

为何jsonb_build_object()不标记为IMMUTABLE?

为什么jsonb_build_object()是STABLE,jsonb_object()却是IMMUTABLE?

先明确PostgreSQL对函数稳定性的核心定义:

  • IMMUTABLE:只要输入参数完全一致,无论何时调用,返回结果都绝对相同,不依赖任何外部状态(比如数据库配置、当前时间、事务上下文等)。
  • STABLE:在单个事务内,相同输入返回相同结果,但跨事务可能因外部状态变化而改变。

接下来拆解两个函数的差异:

1. jsonb_object()的IMMUTABLE特性

jsonb_object()的常规用法是接收键值对数组(比如jsonb_object('{"a", 1, "b", 2}'))或两个分别存储键、值的数组。它的逻辑是纯基于输入数组的静态转换,完全不涉及任何外部依赖,也不会处理可变表达式。只要输入数组内容不变,生成的JSONB对象就完全一致,完全符合IMMUTABLE的要求。

2. jsonb_build_object()的STABLE特性

jsonb_build_object()支持传入任意数量的键值对参数(比如jsonb_build_object('a', 1, 'b', current_timestamp)),它允许将任意表达式作为值传入——包括那些非IMMUTABLE的表达式,比如current_timestamp、now(),甚至查询其他表的结果。

PostgreSQL无法提前预判用户是否会传入可变逻辑的参数,因此只能将该函数标记为STABLE:

  • 在同一个事务内,即便传入STABLE级别的表达式(比如current_timestamp),其值在事务内是固定的,所以jsonb_build_object()的结果也保持固定。
  • 如果将其标记为IMMUTABLE,会强制要求所有传入参数必须是IMMUTABLE,这会极大限制它的使用场景,违背设计初衷。

关于生成列的限制

PostgreSQL要求STORED类型的生成列必须使用IMMUTABLE函数,因为生成列的值是在数据写入时计算并永久存储的,后续不能因外部状态变化而改变。jsonb_build_object()是STABLE,因此无法用于这类生成列;而jsonb_object()是IMMUTABLE,所以可以正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 07:42:35