-- 163_emiss_pk_period_type.sql
-- #1606 follow-up: расширить PK macro_indicator колонкой period_type, чтобы годовой
-- агрегат ('год' → 'year') и Q1 ('I квартал' → 'quarter') за один год не перезаписывали
-- друг друга при ON CONFLICT DO UPDATE (оба дают obs_date=YYYY-01-01).
--
-- Контекст:
--   PR #1687 (#1606) исправил in-memory дедупликацию в parse_emiss_sdmx: ключ дедупа
--   стал трёхкомпонентным (region, obs_date, granularity). Но PK таблицы остался
--   (indicator_type, region, obs_date) — при апсерте в БД коллизия сохранялась.
--   Эта миграция фиксирует PK на стороне БД.
--
-- Что делает:
--   1. Добавляет колонку period_type TEXT NOT NULL DEFAULT 'unknown'.
--      Все существующие строки (CBR, rosstat open-data, domrf) получают 'unknown' —
--      это корректно: у них нет sub-period granularity (они уже различаются по obs_date).
--   2. Бэкфилл: строки source='emiss' обновляем до 'quarter' (единственный
--      активный ЕМИСС-индикатор — income_per_capita, он квартальный; годовых EMISS-
--      строк ещё нет в таблице до этой миграции). Значение ДОЛЖНО совпадать с тем,
--      что пишет UPSERT_EMISS_SQL (_emiss_period_granularity → 'quarter'/'year'/'month',
--      короткая форма), иначе ON CONFLICT не сматчит → дубли при следующем скрейпе.
--   3. Пересоздаёт PRIMARY KEY: старый (indicator_type, region, obs_date) → новый
--      (indicator_type, region, obs_date, period_type).
--   4. Пересоздаёт сопутствующий индекс idx_macro_type_region_date с тем же составом
--      (расширяется автоматически через новый PK-индекс; отдельный индекс DROP+CREATE).
--
-- Зависимости: macro_indicator (migration 123_macro_indicator.sql).
-- Нет VIEW/FK зависимостей от macro_indicator PK (проверено через pg_depend).
-- Idempotent: ADD COLUMN IF NOT EXISTS + IF NOT EXISTS в CREATE INDEX. Повторный
-- прогон безопасен: DROP CONSTRAINT / ADD CONSTRAINT могут упасть если PK уже
-- переименован — обёрнуты в DO $$ BEGIN ... EXCEPTION WHEN ... END $$; блоки.
--
-- Deploy order: SQL migration применяется ПЕРВОЙ (auto-deploy.yml), затем деплоится
-- backend со обновлёнными UPSERT_EMISS_SQL / UPSERT_ROSSTAT_SQL / UPSERT_KEY_RATE_SQL
-- / UPSERT_INFLATION_SQL / UPSERT_ROSSTAT_MONTHLY_SQL (они несут новый конфликт-таргет
-- + period_type в INSERT).

BEGIN;

-- ── 1. Добавить колонку period_type (DEFAULT 'unknown' для всех существующих строк) ──
ALTER TABLE macro_indicator
    ADD COLUMN IF NOT EXISTS period_type TEXT NOT NULL DEFAULT 'unknown';

-- ── 2. Бэкфилл ЕМИСС-строк → 'quarter' ────────────────────────────────────────────
-- Все существующие ЕМИСС-строки — квартальные (income_per_capita). Значение 'quarter'
-- (короткая форма) обязано совпадать с UPSERT_EMISS_SQL, который параметризует
-- period_type из _emiss_period_granularity ('quarter'/'year'/'month'). Иначе после
-- деплоя следующий скрейп вставит 'quarter'-строки, не матчащие 'quarterly' на
-- ON CONFLICT → дубли для каждого квартального наблюдения. Если появятся 'year'-строки
-- (будущие индикаторы) — придут с корректным period_type из скрейпера.
UPDATE macro_indicator
    SET period_type = 'quarter'
    WHERE source = 'emiss'
      AND period_type = 'unknown';

-- ── 3. Пересоздать PRIMARY KEY ────────────────────────────────────────────────────────
-- PostgreSQL не поддерживает ALTER PRIMARY KEY напрямую — нужно DROP + ADD.
-- Ловим случай когда старый PK уже дропнут (повторный прогон).
DO $$
BEGIN
    ALTER TABLE macro_indicator DROP CONSTRAINT macro_indicator_pkey;
EXCEPTION
    WHEN undefined_object THEN
        NULL; -- PK уже удалён (повторный прогон)
    WHEN feature_not_supported THEN
        NULL;
END;
$$;

-- Новый PK включает period_type. Если constraint с этим именем уже существует —
-- ADD CONSTRAINT бросит duplicate_object (42710, дубль имени constraint), ловим.
DO $$
BEGIN
    ALTER TABLE macro_indicator
        ADD CONSTRAINT macro_indicator_pkey
        PRIMARY KEY (indicator_type, region, obs_date, period_type);
EXCEPTION
    WHEN duplicate_object THEN
        NULL; -- constraint с таким именем уже создан (повторный прогон)
    WHEN invalid_table_definition THEN
        NULL; -- уже существует тот же constraint
END;
$$;

-- ── 4. Пересоздать сопутствующий индекс ──────────────────────────────────────────────
-- Старый индекс (без period_type в составе) уже покрыт новым PK-индексом по факту,
-- но явно дропаем и пересоздаём с period_type для консистентности плана запросов.
DROP INDEX IF EXISTS idx_macro_type_region_date;

CREATE INDEX IF NOT EXISTS idx_macro_type_region_date
    ON macro_indicator (indicator_type, region, obs_date DESC, period_type);

COMMIT;
