From c0f27628d2fb53e8e5d190da2132739a2bb2f500 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 28 May 2014 14:21:17 -0400 Subject: [PATCH] Improve regression tests for uuid-ossp. On reflection, the timestamp-advances test might fail if we're unlucky enough for the time_mid field to change between two calls, since uuid_cmp is just bytewise comparison and the field ordering has more significant fields later. Build some field extraction functions so we can do a more honest test of that. Also check that the version and reserved fields contain what they should. --- contrib/uuid-ossp/expected/uuid_ossp.out | 60 ++++++++++++++++++------ contrib/uuid-ossp/sql/uuid_ossp.sql | 49 ++++++++++++++++--- 2 files changed, 88 insertions(+), 21 deletions(-) diff --git a/contrib/uuid-ossp/expected/uuid_ossp.out b/contrib/uuid-ossp/expected/uuid_ossp.out index 986843c897..fe3e325992 100644 --- a/contrib/uuid-ossp/expected/uuid_ossp.out +++ b/contrib/uuid-ossp/expected/uuid_ossp.out @@ -29,40 +29,71 @@ SELECT uuid_ns_x500(); 6ba7b814-9dad-11d1-80b4-00c04fd430c8 (1 row) -SELECT uuid_generate_v1() < uuid_generate_v1(); - ?column? ----------- - t +-- some quick and dirty field extraction functions +-- this is actually timestamp concatenated with clock sequence, per RFC 4122 +CREATE FUNCTION uuid_timestamp_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 15, 4) || substr($1::text, 10, 4) || + substr($1::text, 1, 8) || substr($1::text, 20, 4))::bit(80) + & x'0FFFFFFFFFFFFFFF3FFF' $$ +LANGUAGE SQL STRICT IMMUTABLE; +CREATE FUNCTION uuid_version_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 15, 2))::bit(8) & '11110000' $$ +LANGUAGE SQL STRICT IMMUTABLE; +CREATE FUNCTION uuid_reserved_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 20, 2))::bit(8) & '11000000' $$ +LANGUAGE SQL STRICT IMMUTABLE; +CREATE FUNCTION uuid_multicast_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 25, 2))::bit(8) & '00000011' $$ +LANGUAGE SQL STRICT IMMUTABLE; +CREATE FUNCTION uuid_node(uuid) RETURNS text AS +$$ SELECT substr($1::text, 25) $$ +LANGUAGE SQL STRICT IMMUTABLE; +SELECT uuid_version_bits(uuid_generate_v1()), + uuid_reserved_bits(uuid_generate_v1()), + uuid_multicast_bits(uuid_generate_v1()); + uuid_version_bits | uuid_reserved_bits | uuid_multicast_bits +-------------------+--------------------+--------------------- + 00010000 | 10000000 | 00000000 +(1 row) + +SELECT uuid_version_bits(uuid_generate_v1mc()), + uuid_reserved_bits(uuid_generate_v1mc()), + uuid_multicast_bits(uuid_generate_v1mc()); + uuid_version_bits | uuid_reserved_bits | uuid_multicast_bits +-------------------+--------------------+--------------------- + 00010000 | 10000000 | 00000011 (1 row) -SELECT uuid_generate_v1() < uuid_generate_v1mc(); +-- timestamp+clock sequence should be monotonic increasing in v1 +SELECT uuid_timestamp_bits(uuid_generate_v1()) < uuid_timestamp_bits(uuid_generate_v1()); ?column? ---------- t (1 row) -SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25); +SELECT uuid_timestamp_bits(uuid_generate_v1mc()) < uuid_timestamp_bits(uuid_generate_v1mc()); ?column? ---------- t (1 row) -SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25); +-- node should be stable in v1, but not v1mc +SELECT uuid_node(uuid_generate_v1()) = uuid_node(uuid_generate_v1()); ?column? ---------- t (1 row) -SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25); +SELECT uuid_node(uuid_generate_v1()) <> uuid_node(uuid_generate_v1mc()); ?column? ---------- t (1 row) -SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011'; +SELECT uuid_node(uuid_generate_v1mc()) <> uuid_node(uuid_generate_v1mc()); ?column? ---------- - 00000011 + t (1 row) SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com'); @@ -77,10 +108,11 @@ SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com'); 21f7f8de-8051-5b89-8680-0195ef798b6a (1 row) -SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'; - ?column? ----------- - t +SELECT uuid_version_bits(uuid_generate_v4()), + uuid_reserved_bits(uuid_generate_v4()); + uuid_version_bits | uuid_reserved_bits +-------------------+-------------------- + 01000000 | 10000000 (1 row) SELECT uuid_generate_v4() <> uuid_generate_v4(); diff --git a/contrib/uuid-ossp/sql/uuid_ossp.sql b/contrib/uuid-ossp/sql/uuid_ossp.sql index 29fba21b3f..3b1fa24bc6 100644 --- a/contrib/uuid-ossp/sql/uuid_ossp.sql +++ b/contrib/uuid-ossp/sql/uuid_ossp.sql @@ -6,17 +6,52 @@ SELECT uuid_ns_url(); SELECT uuid_ns_oid(); SELECT uuid_ns_x500(); -SELECT uuid_generate_v1() < uuid_generate_v1(); -SELECT uuid_generate_v1() < uuid_generate_v1mc(); +-- some quick and dirty field extraction functions -SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25); -SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25); -SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25); +-- this is actually timestamp concatenated with clock sequence, per RFC 4122 +CREATE FUNCTION uuid_timestamp_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 15, 4) || substr($1::text, 10, 4) || + substr($1::text, 1, 8) || substr($1::text, 20, 4))::bit(80) + & x'0FFFFFFFFFFFFFFF3FFF' $$ +LANGUAGE SQL STRICT IMMUTABLE; -SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011'; +CREATE FUNCTION uuid_version_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 15, 2))::bit(8) & '11110000' $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE FUNCTION uuid_reserved_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 20, 2))::bit(8) & '11000000' $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE FUNCTION uuid_multicast_bits(uuid) RETURNS varbit AS +$$ SELECT ('x' || substr($1::text, 25, 2))::bit(8) & '00000011' $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE FUNCTION uuid_node(uuid) RETURNS text AS +$$ SELECT substr($1::text, 25) $$ +LANGUAGE SQL STRICT IMMUTABLE; + +SELECT uuid_version_bits(uuid_generate_v1()), + uuid_reserved_bits(uuid_generate_v1()), + uuid_multicast_bits(uuid_generate_v1()); + +SELECT uuid_version_bits(uuid_generate_v1mc()), + uuid_reserved_bits(uuid_generate_v1mc()), + uuid_multicast_bits(uuid_generate_v1mc()); + +-- timestamp+clock sequence should be monotonic increasing in v1 +SELECT uuid_timestamp_bits(uuid_generate_v1()) < uuid_timestamp_bits(uuid_generate_v1()); +SELECT uuid_timestamp_bits(uuid_generate_v1mc()) < uuid_timestamp_bits(uuid_generate_v1mc()); + +-- node should be stable in v1, but not v1mc +SELECT uuid_node(uuid_generate_v1()) = uuid_node(uuid_generate_v1()); +SELECT uuid_node(uuid_generate_v1()) <> uuid_node(uuid_generate_v1mc()); +SELECT uuid_node(uuid_generate_v1mc()) <> uuid_node(uuid_generate_v1mc()); SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com'); SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com'); -SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'; +SELECT uuid_version_bits(uuid_generate_v4()), + uuid_reserved_bits(uuid_generate_v4()); + SELECT uuid_generate_v4() <> uuid_generate_v4(); -- 2.40.0