LOAD '/usr/lib/pgsql/modules/uniqid.so';

CREATE FUNCTION uniqidin(opaque)
   RETURNS opaque
   AS '/usr/lib/pgsql/modules/uniqid.so'
   LANGUAGE 'c';

CREATE FUNCTION uniqidout(opaque)
   RETURNS opaque
   AS '/usr/lib/pgsql/modules/uniqid.so'
   LANGUAGE 'c';

CREATE TYPE uniqueidentifier (
   internallength = 16,
   externallength = 36,
   input = uniqidin,
   output = uniqidout
);

CREATE FUNCTION uniqideq(uniqueidentifier,uniqueidentifier) RETURNS bool
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR = (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqideq,
  negator = <>,
  commutator = =,
  restrict = eqsel,
  join = eqjoinsel,
  sort1 = <,
  sort2 = <,
  hashes
); 

CREATE FUNCTION uniqidne(uniqueidentifier,uniqueidentifier) RETURNS bool
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR <> (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidne,
  negator = =,
  commutator = <>,
  restrict = neqsel,
  join = neqjoinsel
); 

CREATE FUNCTION uniqidlt(uniqueidentifier,uniqueidentifier) RETURNS bool
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR < (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidlt,
  negator = >=,
  commutator = >,
  restrict = scalarltsel,
  join = scalarltjoinsel
); 

CREATE FUNCTION uniqidle(uniqueidentifier,uniqueidentifier) RETURNS bool
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR <= (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidle,
  negator = <,
  commutator = <=,
  restrict = scalarltsel,
  join = scalarltjoinsel
); 

CREATE FUNCTION uniqidgt(uniqueidentifier,uniqueidentifier) RETURNS bool
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR > (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidgt,
  negator = <=,
  commutator = <,
  restrict = scalargtsel,
  join = scalargtjoinsel
); 

CREATE FUNCTION uniqidge(uniqueidentifier,uniqueidentifier) RETURNS bool
  as '/usr/lib/pgsql/modules/uniqid.so'
  language 'C';

CREATE OPERATOR >= (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidge,
  negator = <,
  commutator = <=,
  restrict = scalargtsel,
  join = scalargtjoinsel
); 

CREATE FUNCTION uniqidcmp(uniqueidentifier,uniqueidentifier) RETURNS integer
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

CREATE OPERATOR <=> (
  leftarg = uniqueidentifier,
  rightarg = uniqueidentifier,
  procedure = uniqidcmp
); 

/* set up the indexing infrastructure for btrees - first the operator class */

insert into pg_opclass (opcname, opcdeftype)
select 'uniqueidentifier_ops', oid from pg_type where typname = 'uniqueidentifier';

/* next the operators for particular strategies */
create table btree_opstrategy_tmp (
	oprname name,
	oprstrategy int2);

copy btree_opstrategy_tmp from stdin;
<	1
<=	2
=	3
>=	4
>	5
\.

insert into pg_amop (amopid, amopclaid, amopopr, amopstrategy)
select am.oid, opcl.oid, op.oid, bos.oprstrategy
from pg_am am, pg_opclass opcl,
	btree_opstrategy_tmp bos,
	pg_operator op, pg_type typ
where am.amname = 'btree' and
	opcl.opcname = 'uniqueidentifier_ops' and
	op.oprleft = typ.oid and op.oprright = typ.oid and
	typ.typname = 'uniqueidentifier' and
	op.oprname = bos.oprname;

drop table btree_opstrategy_tmp;

/* finally, the support routine */

insert into pg_amproc (amid, amopclaid, amproc, amprocnum)
select a.oid, b.oid, c.oid, 1
from pg_am a, pg_opclass b, pg_proc c
where a.amname = 'btree' and
	b.opcname = 'uniqueidentifier_ops' and
	c.proname = 'uniqidcmp';

CREATE FUNCTION newid() RETURNS uniqueidentifier
  AS '/usr/lib/pgsql/modules/uniqid.so'
  LANGUAGE 'C';

