-- 158_pzz_zones_ekb_nulls_not_distinct.sql -- #1361 — применить UNIQUE NULLS NOT DISTINCT (rosreestr_id) на СУЩЕСТВУЮЩЕМ проде. -- -- ПОЧЕМУ ОТДЕЛЬНАЯ МИГРАЦИЯ. Правка inline-констрейнта в 85_pzz_zones_ekb.sql -- (CREATE TABLE IF NOT EXISTS) НЕ долетает до прода: 85 уже в _schema_migrations -- → на деплое пропускается, таблица не пересоздаётся, констрейнт остаётся старым -- `UNIQUE (rosreestr_id)` (NULLS DISTINCT). Эта миграция меняет констрейнт на живой -- таблице, чтобы фикс #1361 реально вступил в силу (правка 85 — для fresh-install). -- -- БАГ #1361. rosreestr_id nullable (PKK6 при f=geojson иногда кладёт OBJECTID в -- feature-level id, а не в properties → loader получает NULL). При обычном UNIQUE -- NULL != NULL → ON CONFLICT (rosreestr_id) НЕ матчит существующие NULL-строки → -- каждый повторный sync копит дубли зон. NULLS NOT DISTINCT (PG15+) делает NULL -- сопоставимым → ON CONFLICT матчит → дубли не копятся. -- -- БЕЗОПАСНОСТЬ. Проверено на проде 2026-06-15: pzz_zones_ekb ПУСТА (0 строк), -- текущий констрейнт = pzz_zones_ekb_rosreestr_id_key UNIQUE (rosreestr_id). На пустой -- таблице DROP+ADD не теряет данных и не может упасть на дублях. Прецедент NULLS NOT -- DISTINCT в репо: м.110 (uq_infra_dedupe), м.125, м.140. Prod = PG16. -- Idempotent: DROP CONSTRAINT IF EXISTS + повторный ADD под gate _schema_migrations -- (ровно один раз по NN-порядку). -- Apply after: 157_analyze_hotpath_indexes.sql BEGIN; ALTER TABLE pzz_zones_ekb DROP CONSTRAINT IF EXISTS pzz_zones_ekb_rosreestr_id_key; ALTER TABLE pzz_zones_ekb ADD CONSTRAINT pzz_zones_ekb_rosreestr_id_key UNIQUE NULLS NOT DISTINCT (rosreestr_id); COMMIT;