-- ===========================================================================
-- S6-FUNC-004-TOOLING-LEDGER-CRUD-1
-- MoldToolList（模工具台账）补租户内业务编码唯一索引
--
-- 目的：MoldTypeCode 是模工具台账的业务编码，且被下游按值引用
--       （ProdLineDetail.MoldTypeCode 同租户命中 896 行）。
--       本批为 FUNC-S6-004 增加 CRUD 后，必须由 DB 约束保证租户内唯一 ——
--       仅靠应用层「先查后插」存在 TOCTOU 竞态，并发下会插入重复编码。
--
-- 范围：**只新增一个唯一索引**。
--       不修改 tenant_id 可空性、不改任何列定义、不改字符集/collation、
--       不清洗历史数据、不删除任何行。
--
-- 前置实测（2026-09-01，aidopdev，只读）：
--       MoldToolList 共 290 行，全部 tenant_id = 824585161322565
--       tenant_id IS NULL              = 0
--       MoldTypeCode IS NULL           = 0
--       TRIM(MoldTypeCode) = ''        = 0
--       MoldTypeCode <> TRIM(...)      = 0
--       GROUP BY tenant_id,MoldTypeCode HAVING COUNT(*)>1 = 0 组
--       现有索引：仅 PRIMARY(id)
--
-- ⚠️ tenant_id 可空的已知边界：MySQL 的 UNIQUE 不对 NULL 做相等判定，
--     因此若将来出现 tenant_id IS NULL 的行，唯一性对该行不生效。
--     当前 0 行，且应用层写入一律由服务端从 JWT 盖章 tenant_id，不会产生 NULL。
--     本批**不**把 tenant_id 改成 NOT NULL（属独立的 schema 变更，且实体侧
--     ITenantIdFilter.TenantId 为 long?，硬化会被 CodeFirst 还原）。
--
-- ⚠️ 事务性：MySQL DDL 隐式提交，AutoVersionUpdate 不开显式事务。
--     故所有语句写成可安全重入：索引已存在则整段 no-op。
-- ===========================================================================


-- ---------------------------------------------------------------------------
-- 01 · 前置守卫：新唯一键定义下不得存在重复，否则中止，不带病建索引、不清洗数据
-- ---------------------------------------------------------------------------
SET @dup := (SELECT COUNT(*) FROM (
    SELECT tenant_id, MoldTypeCode
    FROM MoldToolList
    GROUP BY tenant_id, MoldTypeCode
    HAVING COUNT(*) > 1) x);

SET @g := IF(@dup = 0, 'DO 0', 'SELECT RAISE_MOLDTOOLLIST_DUPLICATE_TYPECODE_FOUND');
PREPARE gstmt FROM @g;
EXECUTE gstmt;
DEALLOCATE PREPARE gstmt;


-- ---------------------------------------------------------------------------
-- 02 · 建唯一索引 uk_MoldToolList_tenant_type_code(tenant_id, MoldTypeCode)
--      条件：同名索引不存在才建；已存在则整段 no-op（可重入）
-- ---------------------------------------------------------------------------
SET @idx_exists := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = 'MoldToolList'
      AND INDEX_NAME = 'uk_MoldToolList_tenant_type_code');

SET @s := IF(@idx_exists = 0,
    'CREATE UNIQUE INDEX uk_MoldToolList_tenant_type_code ON MoldToolList (tenant_id, MoldTypeCode)',
    'DO 0');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
