chore: remove legacy account migrations (#404)
This commit is contained in:
parent
3de2dc0962
commit
149458d97f
@ -1,68 +1,60 @@
|
||||
# 前置准备
|
||||
# 历史 UUID 迁移指引(已归档)
|
||||
|
||||
1. 确认扩展
|
||||
登录 PostgreSQL,执行: \dx 看看是否已经有 uuid-ossp 或 pgcrypto。
|
||||
如果没有,就执行:
|
||||
> **说明**:项目已经统一改为直接使用 `schema.sql` 初始化数据库,不再提供单独的 UUID 迁移脚本。本指南仅保留作为旧环境排查的参考,若你是全新部署,可直接执行 `schema.sql` 并忽略本文件。
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
或者:
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
1. **确认扩展**
|
||||
登录 PostgreSQL,执行 `\dx` 检查是否已经启用了 `uuid-ossp` 或 `pgcrypto`。若没有,可执行:
|
||||
|
||||
```sql
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
```
|
||||
|
||||
⚠️ 推荐用 pgcrypto(函数是 gen_random_uuid()),更现代;
|
||||
如果你已经用了 uuid-ossp,脚本里的 uuid_generate_v4() 就能直接用。
|
||||
推荐使用 `pgcrypto` 的 `gen_random_uuid()`;若历史库已启用 `uuid-ossp`,脚本中的 `uuid_generate_v4()` 亦可直接使用。
|
||||
|
||||
2. 备份数据库
|
||||
2. **备份数据库**
|
||||
任何迁移前都应留存快照:
|
||||
|
||||
这是最关键的保险:
|
||||
```bash
|
||||
pg_dump -U <user> -d <dbname> > backup_before_uuid.sql
|
||||
```
|
||||
|
||||
pg_dump -U <user> -d <dbname> > backup_before_uuid.sql
|
||||
3. **执行迁移脚本(仅旧项目)**
|
||||
旧版项目曾通过 `migrate_to_uuid.sql` 完成以下步骤:
|
||||
- 新增 `uuid` 主键列并填充现有数据;
|
||||
- 添加 `user_uuid` 外键字段,与旧的自增 `id` 并行;
|
||||
- 删除旧的 `id`、`user_id` 列并将 `uuid` 设为主键。
|
||||
|
||||
3. 执行迁移
|
||||
如仍需在遗留环境执行,可根据上述逻辑自行编写脚本,或从历史提交中找回旧版 SQL。
|
||||
|
||||
假设你的 schema 在 schema.sql 文件里,迁移脚本在 migrate_to_uuid.sql 文件里。
|
||||
4. **验证结果**
|
||||
迁移完成后进入数据库(`psql -U <user> -d <dbname>`)并检查:
|
||||
|
||||
执行: psql -U <user> -d <dbname> -f migrate_to_uuid.sql
|
||||
```sql
|
||||
\d users
|
||||
\d identities
|
||||
\d sessions
|
||||
```
|
||||
|
||||
预期结构示例:
|
||||
|
||||
这个脚本会做三步:
|
||||
- `users(uuid PRIMARY KEY, username, password, email, created_at …)`
|
||||
- `identities(uuid PRIMARY KEY, user_uuid REFERENCES users(uuid), provider, external_id …)`
|
||||
- `sessions(uuid PRIMARY KEY, user_uuid REFERENCES users(uuid), token, expires_at …)`
|
||||
|
||||
- 新增 uuid 列,填充数据。
|
||||
- 新建 user_uuid 外键字段,保持和旧 id 外键并存。
|
||||
- 删除旧的 id、user_id,把 uuid 设为主键。
|
||||
亦可通过信息架构核对外键:
|
||||
|
||||
4. 验证结果
|
||||
```sql
|
||||
SELECT constraint_name, table_name, column_name, foreign_table_name
|
||||
FROM information_schema.key_column_usage
|
||||
WHERE table_schema = 'public';
|
||||
```
|
||||
|
||||
迁移后,进入数据库: psql -U <user> -d <dbname>
|
||||
5. **回滚策略**
|
||||
若迁移出现问题,可使用备份恢复:
|
||||
|
||||
查看表结构:
|
||||
```bash
|
||||
psql -U <user> -d <dbname> < backup_before_uuid.sql
|
||||
```
|
||||
|
||||
\d users
|
||||
\d identities
|
||||
\d sessions
|
||||
|
||||
|
||||
应该看到:
|
||||
|
||||
users(uuid PRIMARY KEY, username, password, email, created_at …)
|
||||
identities(uuid PRIMARY KEY, user_uuid REFERENCES users(uuid), provider, external_id …)
|
||||
sessions(uuid PRIMARY KEY, user_uuid REFERENCES users(uuid), token, expires_at …)
|
||||
|
||||
再验证外键是否正确:
|
||||
|
||||
SELECT constraint_name, table_name, column_name, foreign_table_name
|
||||
FROM information_schema.key_column_usage
|
||||
WHERE table_schema = 'public';
|
||||
|
||||
回滚策略
|
||||
|
||||
如果迁移出错,可以用之前的备份恢复:
|
||||
|
||||
psql -U <user> -d <dbname> < backup_before_uuid.sql
|
||||
|
||||
总结:
|
||||
|
||||
先启用扩展
|
||||
再运行迁移脚本
|
||||
验证新表结构和外键
|
||||
保留备份,随时可回滚
|
||||
> **小结**:新部署只需运行 `schema.sql`。旧环境若要沿用 UUID 主键改造,可参考上述思路自行调整脚本,并务必在操作前备份。
|
||||
|
||||
@ -1,210 +0,0 @@
|
||||
------------------------------------------------
|
||||
-- STEP 0: 启用 UUID 扩展
|
||||
------------------------------------------------
|
||||
-- 两种方式任选其一,推荐 pgcrypto(更现代)
|
||||
-- 如果数据库还没装扩展,可以先运行 CREATE EXTENSION
|
||||
|
||||
-- 方式一:使用 uuid-ossp
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- 方式二:使用 pgcrypto
|
||||
-- CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- 注意:
|
||||
-- uuid-ossp 用 uuid_generate_v4()
|
||||
-- pgcrypto 用 gen_random_uuid()
|
||||
|
||||
------------------------------------------------
|
||||
-- STEP 1: 平滑迁移(添加 UUID 字段并建立外键)
|
||||
------------------------------------------------
|
||||
|
||||
-- ========== Users ==========
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS uuid UUID DEFAULT uuid_generate_v4();
|
||||
|
||||
UPDATE users SET uuid = uuid_generate_v4() WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE users
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'users'::regclass
|
||||
AND conname = 'users_uuid_unique'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE users ADD CONSTRAINT users_uuid_unique UNIQUE (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ========== Identities ==========
|
||||
ALTER TABLE identities
|
||||
ADD COLUMN IF NOT EXISTS uuid UUID DEFAULT uuid_generate_v4();
|
||||
|
||||
UPDATE identities SET uuid = uuid_generate_v4() WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE identities
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'identities'::regclass
|
||||
AND conname = 'identities_uuid_unique'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE identities ADD CONSTRAINT identities_uuid_unique UNIQUE (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 新增 user_uuid 外键字段
|
||||
ALTER TABLE identities
|
||||
ADD COLUMN IF NOT EXISTS user_uuid UUID;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'identities'
|
||||
AND column_name = 'user_id'
|
||||
AND table_schema = 'public'
|
||||
) THEN
|
||||
EXECUTE 'UPDATE identities i SET user_uuid = u.uuid FROM users u WHERE i.user_id = u.id;';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
ALTER TABLE identities
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'identities'::regclass
|
||||
AND conname = 'identities_user_uuid_fk'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE identities ADD CONSTRAINT identities_user_uuid_fk FOREIGN KEY (user_uuid) REFERENCES users(uuid) ON DELETE CASCADE';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ========== Sessions ==========
|
||||
ALTER TABLE sessions
|
||||
ADD COLUMN IF NOT EXISTS uuid UUID DEFAULT uuid_generate_v4();
|
||||
|
||||
UPDATE sessions SET uuid = uuid_generate_v4() WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE sessions
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'sessions'::regclass
|
||||
AND conname = 'sessions_uuid_unique'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE sessions ADD CONSTRAINT sessions_uuid_unique UNIQUE (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 新增 user_uuid 外键字段
|
||||
ALTER TABLE sessions
|
||||
ADD COLUMN IF NOT EXISTS user_uuid UUID;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'sessions'
|
||||
AND column_name = 'user_id'
|
||||
AND table_schema = 'public'
|
||||
) THEN
|
||||
EXECUTE 'UPDATE sessions s SET user_uuid = u.uuid FROM users u WHERE s.user_id = u.id;';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
ALTER TABLE sessions
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'sessions'::regclass
|
||||
AND conname = 'sessions_user_uuid_fk'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE sessions ADD CONSTRAINT sessions_user_uuid_fk FOREIGN KEY (user_uuid) REFERENCES users(uuid) ON DELETE CASCADE';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
|
||||
------------------------------------------------
|
||||
-- STEP 2: 清理(彻底切换到 UUID 主键)
|
||||
------------------------------------------------
|
||||
|
||||
-- 删除原有的主键约束
|
||||
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey;
|
||||
ALTER TABLE identities DROP CONSTRAINT IF EXISTS identities_pkey;
|
||||
ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_pkey;
|
||||
|
||||
-- 删除旧的 id 外键
|
||||
ALTER TABLE identities DROP CONSTRAINT IF EXISTS identities_user_id_fkey;
|
||||
ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_user_id_fkey;
|
||||
|
||||
-- 设置 uuid 为新的主键
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'users'::regclass
|
||||
AND conname = 'users_pkey'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE users ADD CONSTRAINT users_pkey PRIMARY KEY (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'identities'::regclass
|
||||
AND conname = 'identities_pkey'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE identities ADD CONSTRAINT identities_pkey PRIMARY KEY (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'sessions'::regclass
|
||||
AND conname = 'sessions_pkey'
|
||||
) THEN
|
||||
EXECUTE 'ALTER TABLE sessions ADD CONSTRAINT sessions_pkey PRIMARY KEY (uuid)';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 删除旧的 id 字段
|
||||
ALTER TABLE users DROP COLUMN IF EXISTS id;
|
||||
ALTER TABLE identities DROP COLUMN IF EXISTS id;
|
||||
ALTER TABLE sessions DROP COLUMN IF EXISTS id;
|
||||
|
||||
-- 删除旧的 user_id 外键字段
|
||||
ALTER TABLE identities DROP COLUMN IF EXISTS user_id;
|
||||
ALTER TABLE sessions DROP COLUMN IF EXISTS user_id;
|
||||
|
||||
------------------------------------------------
|
||||
-- Done: 所有表都只用 UUID 作为主键/外键
|
||||
------------------------------------------------
|
||||
@ -1,28 +0,0 @@
|
||||
|
||||
------------------------------------------------
|
||||
-- STEP 2: 切换到 UUID-only
|
||||
------------------------------------------------
|
||||
|
||||
-- 删除旧外键(如果还在的话)
|
||||
ALTER TABLE identities DROP CONSTRAINT IF EXISTS identities_user_id_fkey;
|
||||
ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_user_id_fkey;
|
||||
|
||||
-- 删除旧主键
|
||||
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey;
|
||||
ALTER TABLE identities DROP CONSTRAINT IF EXISTS identities_pkey;
|
||||
ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_pkey;
|
||||
|
||||
-- 设置 uuid 为主键
|
||||
ALTER TABLE users ADD CONSTRAINT users_pkey PRIMARY KEY (uuid);
|
||||
ALTER TABLE identities ADD CONSTRAINT identities_pkey PRIMARY KEY (uuid);
|
||||
ALTER TABLE sessions ADD CONSTRAINT sessions_pkey PRIMARY KEY (uuid);
|
||||
|
||||
-- 删除旧 id 字段(如果还存在)
|
||||
ALTER TABLE users DROP COLUMN IF EXISTS id;
|
||||
ALTER TABLE identities DROP COLUMN IF EXISTS id;
|
||||
ALTER TABLE sessions DROP COLUMN IF EXISTS id;
|
||||
|
||||
-- 删除旧的 user_id 外键字段(如果还存在)
|
||||
ALTER TABLE identities DROP COLUMN IF EXISTS user_id;
|
||||
ALTER TABLE sessions DROP COLUMN IF EXISTS user_id;
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS mfa_totp_secret TEXT,
|
||||
ADD COLUMN IF NOT EXISTS mfa_enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS mfa_secret_issued_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS mfa_confirmed_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
|
||||
@ -1,73 +0,0 @@
|
||||
-- Drop trigger before removing supporting function
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_trigger
|
||||
WHERE tgname = 'trg_users_set_updated_at'
|
||||
AND tgrelid = 'public.users'::regclass
|
||||
) THEN
|
||||
DROP TRIGGER trg_users_set_updated_at ON public.users;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DROP FUNCTION IF EXISTS public.set_updated_at();
|
||||
|
||||
-- Drop indexes introduced by the migration
|
||||
DROP INDEX IF EXISTS public.idx_sessions_user_uuid;
|
||||
DROP INDEX IF EXISTS public.idx_identities_provider;
|
||||
DROP INDEX IF EXISTS public.idx_identities_user_uuid;
|
||||
|
||||
-- Drop foreign keys
|
||||
ALTER TABLE public.sessions
|
||||
DROP CONSTRAINT IF EXISTS sessions_user_fk;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
DROP CONSTRAINT IF EXISTS identities_user_fk;
|
||||
|
||||
-- Drop unique constraints
|
||||
ALTER TABLE public.identities
|
||||
DROP CONSTRAINT IF EXISTS identities_provider_external_id_uk;
|
||||
|
||||
ALTER TABLE public.users
|
||||
DROP CONSTRAINT IF EXISTS users_username_uk;
|
||||
|
||||
ALTER TABLE public.users
|
||||
DROP CONSTRAINT IF EXISTS users_email_uk;
|
||||
|
||||
-- Remove generated column but retain supporting timestamps
|
||||
ALTER TABLE public.users
|
||||
DROP COLUMN IF EXISTS email_verified;
|
||||
|
||||
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN updated_at DROP DEFAULT;
|
||||
|
||||
|
||||
-- Restore uuid columns to neutral defaults
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid DROP DEFAULT,
|
||||
ALTER COLUMN uuid DROP NOT NULL;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid DROP DEFAULT,
|
||||
ALTER COLUMN uuid DROP NOT NULL,
|
||||
ALTER COLUMN user_uuid DROP NOT NULL;
|
||||
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid DROP DEFAULT,
|
||||
ALTER COLUMN uuid DROP NOT NULL;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN user_uuid DROP NOT NULL;
|
||||
|
||||
-- Drop primary keys added by the migration
|
||||
ALTER TABLE public.sessions
|
||||
DROP CONSTRAINT IF EXISTS sessions_pkey;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
DROP CONSTRAINT IF EXISTS identities_pkey;
|
||||
|
||||
ALTER TABLE public.users
|
||||
DROP CONSTRAINT IF EXISTS users_pkey;
|
||||
@ -1,732 +0,0 @@
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- USERS ------------------------------------------------------------------
|
||||
ALTER TABLE public.users
|
||||
ADD COLUMN IF NOT EXISTS uuid uuid;
|
||||
|
||||
UPDATE public.users
|
||||
SET uuid = gen_random_uuid()
|
||||
WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
-- Ensure uuid columns are of the UUID type
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'users'
|
||||
AND column_name = 'uuid'
|
||||
AND udt_name <> 'uuid'
|
||||
) THEN
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'identities'
|
||||
AND column_name = 'uuid'
|
||||
AND udt_name <> 'uuid'
|
||||
) THEN
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'identities'
|
||||
AND column_name = 'user_uuid'
|
||||
AND udt_name <> 'uuid'
|
||||
) THEN
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN user_uuid TYPE uuid USING user_uuid::uuid;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'sessions'
|
||||
AND column_name = 'uuid'
|
||||
AND udt_name <> 'uuid'
|
||||
) THEN
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'sessions'
|
||||
AND column_name = 'user_uuid'
|
||||
AND udt_name <> 'uuid'
|
||||
) THEN
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN user_uuid TYPE uuid USING user_uuid::uuid;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Fill missing UUIDs before enforcing constraints
|
||||
UPDATE public.users SET uuid = gen_random_uuid() WHERE uuid IS NULL;
|
||||
UPDATE public.identities SET uuid = gen_random_uuid() WHERE uuid IS NULL;
|
||||
UPDATE public.sessions SET uuid = gen_random_uuid() WHERE uuid IS NULL;
|
||||
|
||||
-- Ensure NOT NULL on uuid columns
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'users'
|
||||
AND column_name = 'uuid'
|
||||
AND is_nullable = 'YES'
|
||||
) THEN
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'identities'
|
||||
AND column_name = 'uuid'
|
||||
AND is_nullable = 'YES'
|
||||
) THEN
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'sessions'
|
||||
AND column_name = 'uuid'
|
||||
AND is_nullable = 'YES'
|
||||
) THEN
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'identities'
|
||||
AND column_name = 'user_uuid'
|
||||
AND is_nullable = 'YES'
|
||||
) THEN
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'sessions'
|
||||
AND column_name = 'user_uuid'
|
||||
AND is_nullable = 'YES'
|
||||
) THEN
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Ensure defaults for uuid columns
|
||||
DO $$
|
||||
DECLARE
|
||||
current_default text;
|
||||
target_attnum int;
|
||||
BEGIN
|
||||
SELECT attnum INTO target_attnum
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.users'::regclass
|
||||
AND attname = 'uuid'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF target_attnum IS NOT NULL THEN
|
||||
SELECT pg_get_expr(adbin, adrelid)
|
||||
INTO current_default
|
||||
FROM pg_attrdef
|
||||
WHERE adrelid = 'public.users'::regclass
|
||||
AND adnum = target_attnum;
|
||||
|
||||
IF current_default IS DISTINCT FROM 'gen_random_uuid()' THEN
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
current_default text;
|
||||
target_attnum int;
|
||||
BEGIN
|
||||
SELECT attnum INTO target_attnum
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.identities'::regclass
|
||||
AND attname = 'uuid'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF target_attnum IS NOT NULL THEN
|
||||
SELECT pg_get_expr(adbin, adrelid)
|
||||
INTO current_default
|
||||
FROM pg_attrdef
|
||||
WHERE adrelid = 'public.identities'::regclass
|
||||
AND adnum = target_attnum;
|
||||
|
||||
IF current_default IS DISTINCT FROM 'gen_random_uuid()' THEN
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
current_default text;
|
||||
target_attnum int;
|
||||
BEGIN
|
||||
SELECT attnum INTO target_attnum
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.sessions'::regclass
|
||||
AND attname = 'uuid'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF target_attnum IS NOT NULL THEN
|
||||
SELECT pg_get_expr(adbin, adrelid)
|
||||
INTO current_default
|
||||
FROM pg_attrdef
|
||||
WHERE adrelid = 'public.sessions'::regclass
|
||||
AND adnum = target_attnum;
|
||||
|
||||
IF current_default IS DISTINCT FROM 'gen_random_uuid()' THEN
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
|
||||
ALTER TABLE public.users
|
||||
ADD COLUMN IF NOT EXISTS email_verified_at timestamptz;
|
||||
|
||||
ALTER TABLE public.users
|
||||
ADD COLUMN IF NOT EXISTS updated_at timestamptz;
|
||||
|
||||
UPDATE public.users
|
||||
|
||||
SET updated_at = COALESCE(updated_at, now());
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
target_attnum int;
|
||||
current_default text;
|
||||
BEGIN
|
||||
SELECT attnum INTO target_attnum
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.users'::regclass
|
||||
AND attname = 'updated_at'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF target_attnum IS NOT NULL THEN
|
||||
SELECT pg_get_expr(adbin, adrelid)
|
||||
INTO current_default
|
||||
FROM pg_attrdef
|
||||
WHERE adrelid = 'public.users'::regclass
|
||||
AND adnum = target_attnum;
|
||||
|
||||
IF current_default IS DISTINCT FROM 'now()' THEN
|
||||
ALTER TABLE public.users
|
||||
ALTER COLUMN updated_at SET DEFAULT now();
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
att_generated char(1);
|
||||
BEGIN
|
||||
SELECT a.attgenerated
|
||||
INTO att_generated
|
||||
FROM pg_attribute a
|
||||
WHERE a.attrelid = 'public.users'::regclass
|
||||
AND a.attname = 'email_verified'
|
||||
AND NOT a.attisdropped;
|
||||
|
||||
IF att_generated IS NULL THEN
|
||||
EXECUTE 'ALTER TABLE public.users ADD COLUMN email_verified boolean GENERATED ALWAYS AS (email_verified_at IS NOT NULL) STORED';
|
||||
ELSIF att_generated <> 's' THEN
|
||||
EXECUTE 'ALTER TABLE public.users DROP COLUMN email_verified';
|
||||
EXECUTE 'ALTER TABLE public.users ADD COLUMN email_verified boolean GENERATED ALWAYS AS (email_verified_at IS NOT NULL) STORED';
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.set_updated_at()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.updated_at := now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_trigger
|
||||
WHERE tgname = 'trg_users_set_updated_at'
|
||||
AND tgrelid = 'public.users'::regclass
|
||||
AND NOT tgisinternal
|
||||
) THEN
|
||||
CREATE TRIGGER trg_users_set_updated_at
|
||||
BEFORE UPDATE ON public.users
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.set_updated_at();
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
pk_name text;
|
||||
BEGIN
|
||||
SELECT conname INTO pk_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.users'::regclass
|
||||
AND contype = 'p'
|
||||
LIMIT 1;
|
||||
|
||||
IF pk_name IS NULL THEN
|
||||
ALTER TABLE public.users
|
||||
ADD CONSTRAINT users_pkey PRIMARY KEY (uuid);
|
||||
ELSIF pk_name <> 'users_pkey' THEN
|
||||
EXECUTE format('ALTER TABLE public.users RENAME CONSTRAINT %I TO users_pkey', pk_name);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
constraint_name text;
|
||||
email_att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO email_att
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.users'::regclass
|
||||
AND attname = 'email'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF email_att IS NOT NULL THEN
|
||||
SELECT conname INTO constraint_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.users'::regclass
|
||||
AND contype = 'u'
|
||||
AND conkey = ARRAY[email_att]
|
||||
LIMIT 1;
|
||||
|
||||
IF constraint_name IS NULL THEN
|
||||
ALTER TABLE public.users
|
||||
ADD CONSTRAINT users_email_uk UNIQUE (email);
|
||||
ELSIF constraint_name <> 'users_email_uk' THEN
|
||||
EXECUTE format('ALTER TABLE public.users RENAME CONSTRAINT %I TO users_email_uk', constraint_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
constraint_name text;
|
||||
username_att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO username_att
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.users'::regclass
|
||||
AND attname = 'username'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF username_att IS NOT NULL THEN
|
||||
SELECT conname INTO constraint_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.users'::regclass
|
||||
AND contype = 'u'
|
||||
AND conkey = ARRAY[username_att]
|
||||
LIMIT 1;
|
||||
|
||||
IF constraint_name IS NULL THEN
|
||||
ALTER TABLE public.users
|
||||
ADD CONSTRAINT users_username_uk UNIQUE (username);
|
||||
ELSIF constraint_name <> 'users_username_uk' THEN
|
||||
EXECUTE format('ALTER TABLE public.users RENAME CONSTRAINT %I TO users_username_uk', constraint_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
|
||||
-- IDENTITIES --------------------------------------------------------------
|
||||
ALTER TABLE public.identities
|
||||
ADD COLUMN IF NOT EXISTS uuid uuid;
|
||||
|
||||
UPDATE public.identities
|
||||
SET uuid = gen_random_uuid()
|
||||
WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ADD COLUMN IF NOT EXISTS user_uuid uuid;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN user_uuid TYPE uuid USING user_uuid::uuid;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'identities'
|
||||
AND column_name = 'user_id'
|
||||
) THEN
|
||||
UPDATE public.identities i
|
||||
SET user_uuid = u.uuid
|
||||
FROM public.users u
|
||||
WHERE i.user_uuid IS NULL
|
||||
AND u.id = i.user_id;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
ALTER TABLE public.identities
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
pk_name text;
|
||||
BEGIN
|
||||
SELECT conname INTO pk_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.identities'::regclass
|
||||
AND contype = 'p'
|
||||
LIMIT 1;
|
||||
|
||||
IF pk_name IS NULL THEN
|
||||
ALTER TABLE public.identities
|
||||
ADD CONSTRAINT identities_pkey PRIMARY KEY (uuid);
|
||||
ELSIF pk_name <> 'identities_pkey' THEN
|
||||
EXECUTE format('ALTER TABLE public.identities RENAME CONSTRAINT %I TO identities_pkey', pk_name);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
constraint_name text;
|
||||
provider_att smallint;
|
||||
external_att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO provider_att
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.identities'::regclass
|
||||
AND attname = 'provider'
|
||||
AND NOT attisdropped;
|
||||
|
||||
SELECT attnum INTO external_att
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.identities'::regclass
|
||||
AND attname = 'external_id'
|
||||
AND NOT attisdropped;
|
||||
|
||||
IF provider_att IS NOT NULL AND external_att IS NOT NULL THEN
|
||||
SELECT conname INTO constraint_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.identities'::regclass
|
||||
AND contype = 'u'
|
||||
AND conkey = ARRAY[provider_att, external_att]
|
||||
LIMIT 1;
|
||||
|
||||
IF constraint_name IS NULL THEN
|
||||
ALTER TABLE public.identities
|
||||
ADD CONSTRAINT identities_provider_external_id_uk UNIQUE (provider, external_id);
|
||||
ELSIF constraint_name <> 'identities_provider_external_id_uk' THEN
|
||||
EXECUTE format('ALTER TABLE public.identities RENAME CONSTRAINT %I TO identities_provider_external_id_uk', constraint_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
fk_name text;
|
||||
BEGIN
|
||||
SELECT conname INTO fk_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.identities'::regclass
|
||||
AND contype = 'f'
|
||||
AND confrelid = 'public.users'::regclass
|
||||
LIMIT 1;
|
||||
|
||||
IF fk_name IS NULL THEN
|
||||
ALTER TABLE public.identities
|
||||
ADD CONSTRAINT identities_user_fk FOREIGN KEY (user_uuid)
|
||||
REFERENCES public.users(uuid) ON DELETE CASCADE;
|
||||
ELSIF fk_name <> 'identities_user_fk' THEN
|
||||
EXECUTE format('ALTER TABLE public.identities RENAME CONSTRAINT %I TO identities_user_fk', fk_name);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
idx_name text;
|
||||
att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO att
|
||||
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.identities'::regclass
|
||||
AND attname = 'user_uuid'
|
||||
AND NOT attisdropped;
|
||||
|
||||
|
||||
IF att IS NOT NULL THEN
|
||||
|
||||
SELECT cls.relname INTO idx_name
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid = idx.indexrelid
|
||||
WHERE idx.indrelid = 'public.identities'::regclass
|
||||
AND idx.indisunique = FALSE
|
||||
AND idx.indkey = ARRAY[att]::int2vector
|
||||
LIMIT 1;
|
||||
|
||||
IF idx_name IS NULL THEN
|
||||
CREATE INDEX IF NOT EXISTS idx_identities_user_uuid ON public.identities (user_uuid);
|
||||
ELSIF idx_name <> 'idx_identities_user_uuid' THEN
|
||||
EXECUTE format('ALTER INDEX %I RENAME TO idx_identities_user_uuid', idx_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
idx_name text;
|
||||
att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO att
|
||||
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.identities'::regclass
|
||||
AND attname = 'provider'
|
||||
AND NOT attisdropped;
|
||||
|
||||
|
||||
IF att IS NOT NULL THEN
|
||||
SELECT cls.relname INTO idx_name
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid = idx.indexrelid
|
||||
WHERE idx.indrelid = 'public.identities'::regclass
|
||||
AND idx.indisunique = FALSE
|
||||
AND idx.indkey = ARRAY[att]::int2vector
|
||||
|
||||
LIMIT 1;
|
||||
|
||||
IF idx_name IS NULL THEN
|
||||
CREATE INDEX IF NOT EXISTS idx_identities_provider ON public.identities (provider);
|
||||
ELSIF idx_name <> 'idx_identities_provider' THEN
|
||||
EXECUTE format('ALTER INDEX %I RENAME TO idx_identities_provider', idx_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- SESSIONS ----------------------------------------------------------------
|
||||
ALTER TABLE public.sessions
|
||||
ADD COLUMN IF NOT EXISTS uuid uuid;
|
||||
|
||||
UPDATE public.sessions
|
||||
SET uuid = gen_random_uuid()
|
||||
WHERE uuid IS NULL;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid TYPE uuid USING uuid::uuid;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid SET DEFAULT gen_random_uuid();
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN uuid SET NOT NULL;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ADD COLUMN IF NOT EXISTS user_uuid uuid;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN user_uuid TYPE uuid USING user_uuid::uuid;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'sessions'
|
||||
AND column_name = 'user_id'
|
||||
) THEN
|
||||
UPDATE public.sessions s
|
||||
SET user_uuid = u.uuid
|
||||
FROM public.users u
|
||||
WHERE s.user_uuid IS NULL
|
||||
AND u.id = s.user_id;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
ALTER TABLE public.sessions
|
||||
ALTER COLUMN user_uuid SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
pk_name text;
|
||||
BEGIN
|
||||
SELECT conname INTO pk_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.sessions'::regclass
|
||||
AND contype = 'p'
|
||||
LIMIT 1;
|
||||
|
||||
IF pk_name IS NULL THEN
|
||||
ALTER TABLE public.sessions
|
||||
ADD CONSTRAINT sessions_pkey PRIMARY KEY (uuid);
|
||||
ELSIF pk_name <> 'sessions_pkey' THEN
|
||||
EXECUTE format('ALTER TABLE public.sessions RENAME CONSTRAINT %I TO sessions_pkey', pk_name);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
fk_name text;
|
||||
BEGIN
|
||||
SELECT conname INTO fk_name
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'public.sessions'::regclass
|
||||
AND contype = 'f'
|
||||
AND confrelid = 'public.users'::regclass
|
||||
LIMIT 1;
|
||||
|
||||
IF fk_name IS NULL THEN
|
||||
ALTER TABLE public.sessions
|
||||
ADD CONSTRAINT sessions_user_fk FOREIGN KEY (user_uuid)
|
||||
REFERENCES public.users(uuid) ON DELETE CASCADE;
|
||||
ELSIF fk_name <> 'sessions_user_fk' THEN
|
||||
EXECUTE format('ALTER TABLE public.sessions RENAME CONSTRAINT %I TO sessions_user_fk', fk_name);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
idx_name text;
|
||||
att smallint;
|
||||
BEGIN
|
||||
SELECT attnum INTO att
|
||||
|
||||
FROM pg_attribute
|
||||
WHERE attrelid = 'public.sessions'::regclass
|
||||
AND attname = 'user_uuid'
|
||||
AND NOT attisdropped;
|
||||
|
||||
|
||||
IF att IS NOT NULL THEN
|
||||
|
||||
SELECT cls.relname INTO idx_name
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid = idx.indexrelid
|
||||
WHERE idx.indrelid = 'public.sessions'::regclass
|
||||
AND idx.indisunique = FALSE
|
||||
AND idx.indkey = ARRAY[att]::int2vector
|
||||
|
||||
LIMIT 1;
|
||||
|
||||
IF idx_name IS NULL THEN
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_user_uuid ON public.sessions (user_uuid);
|
||||
ELSIF idx_name <> 'idx_sessions_user_uuid' THEN
|
||||
EXECUTE format('ALTER INDEX %I RENAME TO idx_sessions_user_uuid', idx_name);
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
Loading…
Reference in New Issue
Block a user