CREATE OR REPLACE FUNCTION old_to_new(old_id TEXT) RETURNS TEXT AS $$ DECLARE number NUMERIC; timestamp_seconds NUMERIC; timestamp_milliseconds NUMERIC; random NUMERIC; new_number NUMERIC; ulid TEXT; BEGIN -- Convert hexadecimal to numeric number := ('x' || old_id)::bit(128)::numeric; -- Shift by 8 bytes to get the timestamp in seconds timestamp_seconds := number >> 64; timestamp_milliseconds := timestamp_seconds * 1000; -- The first 8 bytes are treated as the random part of the ULID random := number & ((1::numeric << 64) - 1); -- Shift the timestamp by 80 bits to make room for the random part new_number := (timestamp_milliseconds << 80) | random; -- Convert to base32 encoding (simplified version, might need adjustment) ulid := encode(new_number::bytea, 'base64'); RETURN ulid; END; $$ LANGUAGE plpgsql;