web-dev-qa-db-ja.com

JSON要素がテキストでないのになぜテキストを返すのですか?

->>'elementName'を使用してJSON要素にアクセスしようとすると、texttypeが返されます。

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)

ただし、 jsonbは、数値を数値型にマップすると言います ...

テキストのJSON入力をjsonbに変換すると、表8-23に示すように、RFC 7159で説明されているプリミティブ型がネイティブのPostgreSQL型に効果的にマッピングされます。

これはドキュメントから再現された表です、

表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
3
Evan Carroll

現在、内部JSON型にアクセスすることはできません。上記の引用されたドキュメントは、それらがstoredされている方法についてのみ言及しています。 PostgreSQLの疑似タイプanyelement がありますが、そのタイプを返すことはできません。関数はさまざまな型を受け入れるという点で多態的ですが、指定された型を返す必要があります。

演算子はさまざまなタイプでオーバーロードされる可能性がありますが、現時点ではそうではありません。 - 現在 ->>は次のように定義されます

Operator    Right Operand Type  Description
->>         text                Get JSON object field as text

つまり、タイプがどのように保存されていても、アクセスするためにはtextを通過する必要があります。すべてのjsonb演算子はjsonbまたはtextを返します。

タイプがオーバーロードされている場合でも、あいまいさを考慮してください。これはどのように処理されますか。

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

それが理にかなっている場合..それからこれは何をしますか..

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

オーバーロード中->>はシステムをより効率的にするかもしれません、それはまたそれをはるかに複雑にするでしょう。

4
Evan Carroll