fix(dds): починены мёртвые проверки *_not_found + правки урока 3 по ревью

- Зачем:
  - перечитка урока 3 свежим взглядом нашла баг в его эталонном пути: проверки
    device_not_found/geo_not_found/location_not_found в DDS никогда не срабатывали,
    а текст урока ошибочно утверждал, что метки ставятся
- Что:
  - sql/dds/30_ods_to_dds.sql: добавлен SETTINGS join_use_nulls=1 в оба
    INSERT...SELECT. Без него LEFT JOIN на несовпадении клал в assumeNotNull(click_id)
    нулевой UUID (не NULL), и if(...IS NULL, ['*_not_found'], []) молча давал []
    (мёртвый код). Тот же класс бага про типы/NULL, что kafka_ts в уроке 1
  - docs/course/lessons/03_ods_to_dds.md: убраны ложные claim'ы про geo_not_found/
    location_not_found, формулировки приведены к реальному поведению (клик без гео
    остаётся с пустыми полями NULL; целостность событий — через orphan_events);
    поправлена опечатка «список всех клиентов» → «всех кликов»
- Проверка:
  - синтетический тест join_use_nulls=1: клик в device без geo → в ods_parse_errors
    появляются geo_not_found и geo_country_missing (до фикса — пусто)
  - LIMIT=50 make transform после фикса: dds.click=26, dds.event=50,
    orphan_events=0, ни одной строки с непустым ods_parse_errors (вывод не изменился —
    на чистом срезе несовпадений нет)
This commit is contained in:
2026-06-05 21:58:44 +03:00
parent d55f183fc9
commit 5f5312c70c
2 changed files with 28 additions and 19 deletions
+9 -2
View File
@@ -101,7 +101,11 @@ LEFT JOIN (
FROM ods.geo_by_click
WHERE click_id IS NOT NULL
GROUP BY click_id
) AS g ON g.click_id = c.click_id;
) AS g ON g.click_id = c.click_id
-- join_use_nulls=1: при несовпадении LEFT JOIN кладёт в правые колонки NULL, а не дефолт.
-- Без этого assumeNotNull(click_id) на несовпавшей строке стал бы нулевым UUID (не NULL),
-- и проверки if(d.click_id IS NULL, ...) / if(g.click_id IS NULL, ...) молча не сработали бы.
SETTINGS join_use_nulls = 1;
-- ----------------------------------------------------------------------------
-- Сущность: dds.event (объединяет browser + location)
@@ -165,4 +169,7 @@ LEFT JOIN (
FROM ods.location_event
WHERE event_id IS NOT NULL
GROUP BY event_id
) AS l ON l.event_id = b.event_id;
) AS l ON l.event_id = b.event_id
-- join_use_nulls=1: чтобы при отсутствии location поле l.event_id было NULL, а не нулевым UUID,
-- и проверка if(l.event_id IS NULL, ['location_not_found'], []) реально срабатывала.
SETTINGS join_use_nulls = 1;