Может ли CROSS JOIN быть «неявно БОЛЬНЫМ»? - PullRequest
2 голосов
/ 08 октября 2019

Предположим следующую, довольно упрощенную базу данных:

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}');

, поэтому у нас есть следующая таблица:

# SELECT * FROM test_table ;
 name  |           data
-------+--------------------------
 name1 | {"a": 1, "b": 2}
 name2 | {"c": 3, "d": 4, "e": 5}
(2 rows)

Теперь я видел такой запрос:

# SELECT * FROM test_table CROSS JOIN JSONB_EACH(test_table.data);

возвращает следующий результат:

 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)

Моя проблема в том, что я не понимаю, что здесь происходит. С одной стороны, это выглядит как LATERAL соединение, так как правая часть JOIN относится к левой, и результат совершенно логичен. С другой стороны, в руководстве говорится следующее:

(Без LATERAL каждый подпункт SELECT оценивается независимо и поэтому не может перекрестно ссылаться на любой другой элемент FROM.)

и это:

Исходные таблицы столбцов должны быть INNER или LEFT, присоединенными к элементу LATERAL […]

(см. здесь ), и, конечно, CROSS JOIN не возвращает n × m строк (как эта страница * 1041)* говорит).

Мой вопрос: не противоречит ли результат запроса выше руководству? Если нет, значит ли это, что JSONB_EACH как-то лечится специально? (Это я нахожу удивительным.)

1 Ответ

3 голосов
/ 08 октября 2019

Если нет, значит ли это, что JSONB_EACH каким-то образом обрабатывается специально?

Да, это так, потому что это табличная функция (так называемая "set returning function"))

Цитата из руководства

Табличным функциям, появляющимся в FROM, также может предшествовать ключевое слово LATERAL, , но для функций ключевое словонеобязательно ;аргументы функции могут содержать ссылки на столбцы, предоставленные предшествующими элементами FROM в любом случае.

(выделено мной)

...