gohorsejobs/backend/migrations/009_create_uuid_v7_function.sql
Tiago Yamamoto 5f3430bd98 fix: reorder uuid_generate_v7 migration to run before tables that use it
- Rename 021_create_uuid_v7_function.sql to 009_create_uuid_v7_function.sql
- Add CREATE EXTENSION IF NOT EXISTS pgcrypto for gen_random_bytes()
- Remove obsolete 022_migrate_to_uuid_v7.sql (already handled by table def)

This fixes the error where migration 017 tried to use uuid_generate_v7()
before it was created.
2025-12-24 11:52:44 -03:00

60 lines
1.9 KiB
PL/PgSQL

-- Migration: Create UUID v7 generation function
-- Description: PostgreSQL function to generate UUID v7 (time-ordered UUIDs)
-- UUID v7 format: tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx
-- Where: t = timestamp, 7 = version, y = variant, x = random
-- Enable pgcrypto extension for gen_random_bytes()
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- Create or replace the uuid_generate_v7 function
CREATE OR REPLACE FUNCTION uuid_generate_v7()
RETURNS uuid AS $$
DECLARE
unix_ts_ms bigint;
uuid_bytes bytea;
BEGIN
-- Get current Unix timestamp in milliseconds
unix_ts_ms := (EXTRACT(EPOCH FROM clock_timestamp()) * 1000)::bigint;
-- Build the UUID bytes:
-- First 6 bytes: timestamp (48 bits)
-- Next 2 bytes: version (4 bits) + random (12 bits)
-- Last 8 bytes: variant (2 bits) + random (62 bits)
uuid_bytes := set_byte(
set_byte(
set_byte(
set_byte(
set_byte(
set_byte(
gen_random_bytes(16),
0, (unix_ts_ms >> 40)::int
),
1, (unix_ts_ms >> 32)::int
),
2, (unix_ts_ms >> 24)::int
),
3, (unix_ts_ms >> 16)::int
),
4, (unix_ts_ms >> 8)::int
),
5, unix_ts_ms::int
);
-- Set version 7 (0111) in byte 6
uuid_bytes := set_byte(uuid_bytes, 6, (get_byte(uuid_bytes, 6) & 15) | 112);
-- Set variant RFC 4122 (10xx) in byte 8
uuid_bytes := set_byte(uuid_bytes, 8, (get_byte(uuid_bytes, 8) & 63) | 128);
RETURN encode(uuid_bytes, 'hex')::uuid;
END;
$$ LANGUAGE plpgsql VOLATILE;
-- Comment
COMMENT ON FUNCTION uuid_generate_v7() IS 'Generates a UUID v7 (time-ordered) - RFC 9562 compliant';
-- Test the function
DO $$
BEGIN
RAISE NOTICE 'UUID v7 test: %', uuid_generate_v7();
END $$;