Assume the following, rather simplistic database:
CREATE TABLE test_table(
name TEXT,
data JSONB
);
INSERT INTO test_table VALUES ('name1', '{"a": 1, "b": 2}'), ('name2', '{"c": 3, "d": 4, "e": 5}');
so we have the following table:
# SELECT * FROM test_table ;
name | data
-------+--------------------------
name1 | {"a": 1, "b": 2}
name2 | {"c": 3, "d": 4, "e": 5}
(2 rows)
Now I've seen a query like this:
# SELECT * FROM test_table CROSS JOIN JSONB_EACH(test_table.data);
returning the following result:
name | data | key | value
-------+--------------------------+-----+-------
name1 | {"a": 1, "b": 2} | a | 1
name1 | {"a": 1, "b": 2} | b | 2
name2 | {"c": 3, "d": 4, "e": 5} | c | 3
name2 | {"c": 3, "d": 4, "e": 5} | d | 4
name2 | {"c": 3, "d": 4, "e": 5} | e | 5
(5 rows)
My problem is that I do not understand what happens here. On the one
hand, this looks like a LATERAL
join, since the right-hand side of
JOIN
refers to the left-hand one, and the result is perfectly
logical. On the other hand, the manual says this:
(Without
LATERAL
, each sub-SELECT
is evaluated independently and so cannot cross-reference any otherFROM
item.)
and this:
The column source table(s) must be
INNER
orLEFT
joined to theLATERAL
item […]
(see here), and of course the CROSS JOIN
does not return n×m
rows (as this page says).
My question is: does the result of the query above not contradict the
manual? If not, does that mean that JSONB_EACH
is somehow treated
specially? (That I would find surprising.)
If not, does that mean that JSONB_EACH is somehow treated specially?
Yes it is, because it's a table function (aka "set returning function")
Quote from the manual
Table functions appearing in FROM can also be preceded by the key word LATERAL, but for functions the key word is optional; the function's arguments can contain references to columns provided by preceding FROM items in any case.
(emphasis mine)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With