为什么 JSON 元素在不是文本时返回文本?

Eva*_*oll 4 postgresql datatypes database-internals json operator

当我尝试使用一个 JSON 元素访问时,->>'elementName'我得到了一个text类型。

SELECT pg_typeof(x1->>'a'), jsonb_typeof(x2)
FROM ( VALUES
  ('{"a":5}'::jsonb, '5'::jsonb)
) AS t(x1,x2);

 pg_typeof | jsonb_typeof 
-----------+--------------
 text      | number
(1 row)
Run Code Online (Sandbox Code Playgroud)

但是,jsonb表示它将数字映射到数字类型......

将文本 JSON 输入转换为 jsonb 时,RFC 7159 描述的原始类型有效地映射到本机 PostgreSQL 类型,如表 8-23 所示。

这是从文档中复制的表格,

表 8-23。JSON 原始类型和对应的 PostgreSQL 类型

JSON primitive type     PostgreSQL type  Notes
string                  text             \u0000 is disallowed, as are non-ASCII Unicode escapes if database encoding is not UTF8
number                  numeric          NaN and infinity values are disallowed
boolean                 boolean          Only lowercase true and false spellings are accepted
null                    (none)           SQL NULL is a different concept
Run Code Online (Sandbox Code Playgroud)

Eva*_*oll 5

目前无法访问内部 JSON 类型。上面引用的文件只提到了它们的存储方式PostgreSQL 中anyelement有一个伪类型,但你不能返回那个类型。函数是多态的,因为它们接受不同的类型,但它们必须返回指定的类型。

运算符可以针对不同类型重载,但目前并非如此。目前->>定义为

Operator    Right Operand Type  Description
->>         text                Get JSON object field as text
Run Code Online (Sandbox Code Playgroud)

这意味着无论类型如何存储,都必须通过text才能访问它。所有jsonb运算符都返回jsonbor text

即使类型被重载,也要考虑歧义,这将如何处理。

SELECT pg_typeof(x1->>'a'), jsonb_typeof(x2)
FROM ( VALUES
  ('{"a":5}'::jsonb, '5'),
  ('{"a":true}'::jsonb, 'true'::jsonb)
) AS t(x1,x2);
Run Code Online (Sandbox Code Playgroud)

如果这是有道理的..那么这有什么作用..

SELECT sum(x1->>'a')
FROM ( VALUES
  ('{"a":5}'::jsonb, '5'),
  ('{"a":true}'::jsonb, 'true'::jsonb)
) AS t(x1,x2);
Run Code Online (Sandbox Code Playgroud)

虽然过载->>可能会使系统更高效,但也会使其变得更加复杂。