Skip to content

Instantly share code, notes, and snippets.

@pmarreck
Created December 13, 2023 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmarreck/4c0cf35b06eccbcea087875a6ce8fc39 to your computer and use it in GitHub Desktop.
Save pmarreck/4c0cf35b06eccbcea087875a6ce8fc39 to your computer and use it in GitHub Desktop.
Generate a UUIDv7 with a PL/pgSQL function
-- IETF Draft Spec: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-01.html
CREATE SEQUENCE uuidv7_seq MAXVALUE 4095; -- A 12-bit sequence
CREATE OR REPLACE FUNCTION generate_uuidv7()
RETURNS uuid AS $$
DECLARE
unixts bigint;
msec bigint;
seq bigint;
rand bigint;
uuid_hex varchar;
BEGIN
-- Get current UNIX epoch in milliseconds
unixts := (EXTRACT(EPOCH FROM clock_timestamp()) * 1000)::bigint;
-- Extract milliseconds
msec := unixts % 1000; -- Milliseconds
-- Get next value from the sequence for the "motonic clock sequence counter" value
seq := NEXTVAL('uuidv7_seq');
-- Generate a random 62-bit number
rand := (RANDOM() * 4611686018427387903)::bigint; -- 62-bit random number
-- Construct the UUID
uuid_hex := LPAD(TO_HEX(((unixts << 28) + (msec << 16) + (7 << 12) + seq)), 16, '0') ||
LPAD(TO_HEX((2 << 62) + rand), 16, '0');
-- Return the UUID
RETURN uuid_hex::uuid;
END;
$$ LANGUAGE plpgsql VOLATILE;
SELECT generate_uuidv7();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment