I cannot grasp how the JSONB_ARRAY_ELEMENTS
function works and why it expands the rows the way it does.
Please, consider this simplistic table:
CREATE TABLE test_jsonb_expand (
id SERIAL PRIMARY KEY,
data JSONB NOT NULL
);
We fill it with example data:
INSERT INTO test_jsonb_expand (data)
VALUES
('{"events": [{"id": 1, "type": "enter"}, {"id": 141, "type": "exit"}], "other_data": ["whatever#1"]}'),
('{"events": [{"id": 1, "type": "enter"}, {"id": 150, "type": "exit"}], "other_data": ["whatever#1", "whatever#2"]}'),
('{"events": [{"id": 1, "type": "enter"}, {"id": 300, "type": "exit"}], "other_data": ["whatever#1", "whatever#2", "whatever#3"]}');
And then run this query:
SELECT
id,
JSONB_ARRAY_ELEMENTS(data->'events')->>'id' AS event_id,
JSONB_ARRAY_ELEMENTS(data->'events')->>'type' AS event_type,
JSONB_ARRAY_ELEMENTS(data->'other_data')->>0 AS other_data
FROM
test_jsonb_expand;
In my mind it is not a query that can be meaningfully run, as it’s not clear how to expand the multiple JSONB_ARRAY_ELEMENTS
invocations on different values of the data
column. However, postgres returns a meaningful enough result:
id | event_id | event_type | other_data
----+----------+------------+------------
1 | 1 | enter | whatever#1
1 | 141 | exit |
2 | 1 | enter | whatever#1
2 | 150 | exit | whatever#2
3 | 1 | enter | whatever#1
3 | 300 | exit | whatever#2
3 | | | whatever#3
Which kind of makes sense, but kind of doesn’t in a way.
- Why are the results insertion-ordered?
- Is this a reliable behavior? Or it’s just an implementation detail and a large enough dataset is not guaranteed to work this way?
- How does postgres know how to expand this kind of query?
- Is there any documentation regarding this syntax?
Sorry, if there are too many questions. A link to the docs would be sufficient, as I haven’t been able to find an explanation.