Improve regression tests for uuid-ossp.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 28 May 2014 18:21:17 +0000 (14:21 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 28 May 2014 18:21:17 +0000 (14:21 -0400)
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
contrib/uuid-ossp/sql/uuid_ossp.sql

index 986843c8976441fe1826cb89c177aa37b1282f18..fe3e3259922b5ea8344f18cfddb65f24c643effa 100644 (file)
@@ -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();
index 29fba21b3f75e8af8e316890171b1a9247b10cb0..3b1fa24bc6b36e0bdd3850853a79051f03a79e65 100644 (file)
@@ -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();