11/* =========================================================
2- * users - provider / email 정책 반영
2+ * users - provider / email 정책 반영 (FIXED)
3+ * - 기존 email UNIQUE는 "인덱스"가 아니라 "제약조건(UNIQUE CONSTRAINT)"일 수 있어
4+ * DROP INDEX가 아니라 DROP CONSTRAINT가 필요함.
5+ * - 환경별로 (1) UNIQUE CONSTRAINT, (2) UNIQUE INDEX 둘 다 케어
36 * ========================================================= */
47
5- /* 1) provider_type, provider_id 컬럼 추가 */
8+ -- 1) provider_type, provider_id 컬럼 추가
69ALTER TABLE users
710 ADD COLUMN IF NOT EXISTS provider_type VARCHAR (50 );
811
912ALTER TABLE users
1013 ADD COLUMN IF NOT EXISTS provider_id VARCHAR (255 );
1114
12- /* 2) 기존 row → provider_type = 'LOCAL' */
15+ -- 2) 기존 row → provider_type = 'LOCAL'
1316UPDATE users
1417SET provider_type = ' LOCAL'
1518WHERE provider_type IS NULL ;
1619
17-
18- /* 3) provider_type 기본값 + NOT NULL */
20+ -- 3) provider_type 기본값 + NOT NULL
1921ALTER TABLE users
2022 ALTER COLUMN provider_type SET DEFAULT ' LOCAL' ;
2123
@@ -24,15 +26,33 @@ ALTER TABLE users
2426
2527
2628/* =========================================================
27- * email partial unique
29+ * email unique 해제 -> partial unique로 전환
2830 * ========================================================= */
2931
30- /* 4) 기존 email UNIQUE 인덱스 제거 */
32+ -- 4) 기존 email UNIQUE 해제
33+ -- (A) UNIQUE CONSTRAINT 로 걸려있으면 CONSTRAINT를 제거
34+ -- (B) UNIQUE INDEX 로만 걸려있으면 INDEX를 제거
3135DO
3236$$
3337 DECLARE
38+ con_name text ;
3439 idx_name text ;
3540 BEGIN
41+ /* (A) users 테이블의 UNIQUE 제약조건 중 (email) 을 포함하는 것 찾기 */
42+ SELECT c .conname
43+ INTO con_name
44+ FROM pg_constraint c
45+ JOIN pg_class t ON t .oid = c .conrelid
46+ WHERE t .relname = ' users'
47+ AND c .contype = ' u'
48+ AND pg_get_constraintdef(c .oid ) ILIKE ' %(email)%'
49+ LIMIT 1 ;
50+
51+ IF con_name IS NOT NULL THEN
52+ EXECUTE format(' ALTER TABLE users DROP CONSTRAINT IF EXISTS %I' , con_name);
53+ END IF;
54+
55+ /* (B) 혹시 constraint 없이 unique index로만 잡혀있는 케이스 */
3656 SELECT i .relname
3757 INTO idx_name
3858 FROM pg_class t
5171 END
5272$$;
5373
54- /* 5) email IS NOT NULL 인 경우만 유니크 */
74+ -- 5) email IS NOT NULL 인 경우만 유니크
5575CREATE UNIQUE INDEX IF NOT EXISTS uk_users_email_not_null
5676 ON users (email)
5777 WHERE email IS NOT NULL ;
@@ -61,7 +81,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_users_email_not_null
6181 * provider unique (소셜 계정만)
6282 * ========================================================= */
6383
64- /* 6) 소셜 계정에 대해서만 (provider_type, provider_id) 유니크 */
84+ -- 6) 소셜 계정에 대해서만 (provider_type, provider_id) 유니크
6585CREATE UNIQUE INDEX IF NOT EXISTS uk_users_provider_social
6686 ON users (provider_type, provider_id)
6787 WHERE provider_type <> ' LOCAL' ;
0 commit comments