Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does JSON null not cast to SQL null in postgres?

So the following PostgreSQL snippet returns null, as it should:

select ('{"id": null}'::json->'id')

Intuitively, one would expect the following statement to return null or an empty string:

select ('{"id": null}'::json->'id')::TEXT

Instead it returns the string "null". Why?

Additionally,

select ('{"id": null}'::json->'id')::INTEGER

returns cannot cast type json to integer and

select ('{"id": null}'::json->'id')::TEXT::INTEGER

returns invalid input syntax for integer: "null". (The use case here is casting a JSON null to a SQL null in an INTEGER column.)

There's a similar question with a somewhat-unintelligible answer that seems to boil down to "JSON nulls and SQL nulls are slightly different" and no further explanation. Can someone help me understand what is going on here? This apparent behavior seems crazy!

How does one get around this cleanly? Testing for string "null" screams of code stink, and refactoring to test every single potential node for null/"null" before casting is equally yuck. Any other ideas?

like image 525
Tom Corelis Avatar asked Aug 26 '16 18:08

Tom Corelis


People also ask

Can JSON be NULL Postgres?

Expands a JSON array to a set of text values. Returns the type of the outermost JSON value as a text string. Possible types are object, array, string, number, boolean, and null.

IS NOT NULL JSON SQL?

Note: A JSON value of null is a value as far as SQL is concerned. It is not NULL, which in SQL represents the absence of a value (missing, unknown, or inapplicable data). In particular, SQL condition IS NULL returns false for a JSON null value, and SQL condition IS NOT NULL returns true.

Is JSON supported in PostgreSQL?

PostgreSQL offers two types for storing JSON data: json and jsonb . To implement efficient query mechanisms for these data types, PostgreSQL also provides the jsonpath data type described in Section 8.14. 7. The json and jsonb data types accept almost identical sets of values as input.

How does Postgres handle NULL?

In PostgreSQL, NULL means no value. In other words, the NULL column does not have any value. It does not equal 0, empty string, or spaces. The NULL value cannot be tested using any equality operator like “=” “!=


2 Answers

Use the ->> operator for retrieving the json field.

This should work and return null (as in, no value) correctly for both:

select ('{"id": null}'::json->>'id')::text
select ('{"id": null}'::json->>'id')::integer

I've made a fiddle that demostrates it

PS: to get the string "null", you'd need to define your json as: {"id": "null"}

like image 184
Jcl Avatar answered Nov 13 '22 17:11

Jcl


You probably need to use the json_typeof operator to figure out what you have in the JSON type that is returned by ->

select json_typeof('{"id": 4}'::json->'id'),
       json_typeof('{"id": "null"}'::json->'id'),
       json_typeof('{"id": null}'::json->'id');

Using ->> instead guarantees you a text string value, but then you cannot distinguish between null and "null"

like image 28
Michael Dillon Avatar answered Nov 13 '22 17:11

Michael Dillon