create or replace function uuid_bytespp(howmany integer) returns bytea as $$ declare bytes bytea; begin bytes = rpad('', howmany); for i in 0 .. howmany-1 loop bytes := set_byte(bytes, i, (random()*256)::integer); end loop; return bytes; end; $$ language 'plpgsql'; create or replace function uuid_v1pp() returns uuid as $$ declare bytes bytea; byte integer; str text; id uuid; tslow bytea; tsmid bytea; tshigh bytea; tsi bigint; begin -- 122192928000000000 select extract(epoch from now() - '1582-10-15 00:00:00 UTC'::timestamp with time zone)::bigint * 10000000 + extract(microseconds from now() - '1582-10-15 00:00:00 UTC'::timestamp with time zone)::integer % 1000000 * 10 into tsi ; tslow := decode(lpad(to_hex(tsi & x'ffffffff'::bigint), 8, '0'), 'hex'); tsmid := decode(lpad(to_hex((tsi>>32) & x'ffff'::bigint), 4, '0'), 'hex'); tshigh := decode(lpad(to_hex((tsi>>48) & x'ffff'::bigint), 4, '0'), 'hex'); -- we don't store any state, so the clock sequence is random, -- and we don't have any way to get the macaddr, so that's -- random too. though we set the multicast bit (the real one, -- not the one in the rfc) bytes := tslow || tsmid || tshigh || uuid_bytespp(8); byte = get_byte(bytes, 6); byte = (byte & 15) | 16; bytes = set_byte(bytes, 6, byte); byte = get_byte(bytes, 8); byte = (byte & 63) | 128; bytes = set_byte(bytes, 8, byte); byte = get_byte(bytes, 10); byte = (byte & 127) | 128; bytes = set_byte(bytes, 10, byte); str = encode(bytes, 'hex'); id = str::uuid; return id; end; $$ language 'plpgsql'; create or replace function uuid_v4pp() returns uuid as $$ declare bytes bytea; byte integer; str text; id uuid; begin bytes = uuid_bytespp(16); byte = get_byte(bytes, 6); byte = (byte & 15) | 64; bytes = set_byte(bytes, 6, byte); byte = get_byte(bytes, 8); byte = (byte & 63) | 128; bytes = set_byte(bytes, 8, byte); str = encode(bytes, 'hex'); id = str::uuid; return id; end; $$ language 'plpgsql'; create or replace function uuid_v3pp(ns uuid, content bytea) returns uuid as $$ declare bytes bytea; nsbytes bytea; byte integer; str text; id uuid; begin nsbytes = decode(regexp_replace(ns::text, '-', '', 'g'), 'hex'); bytes = decode(md5(nsbytes || content), 'hex'); byte = get_byte(bytes, 6); byte = (byte & 15) | 48; bytes = set_byte(bytes, 6, byte); byte = get_byte(bytes, 8); byte = (byte & 63) | 128; bytes = set_byte(bytes, 8, byte); str = encode(bytes, 'hex'); id = str::uuid; return id; end; $$ language 'plpgsql'; create or replace function uuid_v5pp(ns uuid, content bytea) returns uuid as $$ declare bytes bytea; nsbytes bytea; byte integer; str text; id uuid; begin nsbytes = decode(regexp_replace(ns::text, '-', '', 'g'), 'hex'); bytes = substring(decode(sha1(nsbytes || content), 'hex') from 1 for 16); byte = get_byte(bytes, 6); byte = (byte & 15) | 80; bytes = set_byte(bytes, 6, byte); byte = get_byte(bytes, 8); byte = (byte & 63) | 128; bytes = set_byte(bytes, 8, byte); str = encode(bytes, 'hex'); id = str::uuid; return id; end; $$ language 'plpgsql';