BEGIN TRANSACTION;

-- TXTIDX type

CREATE FUNCTION txtidx_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE FUNCTION txtidx_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE TYPE txtidx (
internallength = -1,
input = txtidx_in,
output = txtidx_out
);

CREATE FUNCTION txt2txtidx(text)
RETURNS txtidx
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE FUNCTION txtidxsize(txtidx)
RETURNS int4
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

--QUERYTYPES
--without morphology
CREATE FUNCTION qtxt_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE FUNCTION qtxt_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE TYPE query_txt (
internallength = -1,
input = qtxt_in,
output = qtxt_out
);

--with morphology
CREATE FUNCTION mqtxt_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE TYPE mquery_txt (
internallength = -1,
input = mqtxt_in,
output = qtxt_out
);

--only for debug
CREATE FUNCTION querytree(query_txt)
RETURNS text
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE FUNCTION querytree(mquery_txt)
RETURNS text
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

--operations
CREATE FUNCTION execqtxt(txtidx, query_txt) RETURNS bool
        AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);

COMMENT ON FUNCTION execqtxt(txtidx, query_txt) IS 'boolean operation with text index';

CREATE FUNCTION execqtxt(txtidx, mquery_txt) RETURNS bool
        AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);

COMMENT ON FUNCTION execqtxt(txtidx, mquery_txt) IS 'boolean operation with text index';

CREATE FUNCTION rexecqtxt(query_txt, txtidx) RETURNS bool
        AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);

COMMENT ON FUNCTION rexecqtxt(query_txt, txtidx) IS 'boolean operation with text index';

CREATE FUNCTION rexecqtxt(mquery_txt, txtidx) RETURNS bool
        AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);

COMMENT ON FUNCTION rexecqtxt(mquery_txt, txtidx) IS 'boolean operation with text index';

CREATE OPERATOR @@ (
   LEFTARG = txtidx, RIGHTARG = query_txt, PROCEDURE = execqtxt,
   COMMUTATOR = '~@', RESTRICT = contsel, JOIN = contjoinsel
);

CREATE OPERATOR ~@ (
   LEFTARG = query_txt, RIGHTARG = txtidx, PROCEDURE = rexecqtxt,
   COMMUTATOR = '@@', RESTRICT = contsel, JOIN = contjoinsel
);

CREATE OPERATOR ## (
   LEFTARG = txtidx, RIGHTARG = mquery_txt, PROCEDURE = execqtxt,
   COMMUTATOR = '~#', RESTRICT = contsel, JOIN = contjoinsel
);

CREATE OPERATOR ~# (
   LEFTARG = mquery_txt, RIGHTARG = txtidx, PROCEDURE = rexecqtxt,
   COMMUTATOR = '##', RESTRICT = contsel, JOIN = contjoinsel
);

--Trigger
create function tsearch() returns opaque as
        'MODULE_PATHNAME'
        language 'C';

--GiST
--GiST key type
CREATE FUNCTION gtxtidx_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE FUNCTION gtxtidx_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);

CREATE TYPE gtxtidx (
internallength = -1,
input = gtxtidx_in,
output = gtxtidx_out
);

CREATE FUNCTION gtxtidx_consistent(gtxtidx,opaque,int4) RETURNS bool
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

CREATE FUNCTION gtxtidx_compress(opaque) RETURNS opaque
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

CREATE FUNCTION gtxtidx_decompress(opaque) RETURNS opaque
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

CREATE FUNCTION gtxtidx_penalty(opaque,opaque,opaque) RETURNS opaque
        AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);

CREATE FUNCTION gtxtidx_picksplit(opaque, opaque) RETURNS opaque
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

CREATE FUNCTION gtxtidx_union(bytea, opaque) RETURNS _int4
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

CREATE FUNCTION gtxtidx_same(gtxtidx, gtxtidx, opaque) RETURNS opaque
        AS 'MODULE_PATHNAME' LANGUAGE 'c';

INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
    VALUES (
        (SELECT oid FROM pg_am WHERE amname = 'gist'),
        'gist_txtidx_ops',
        (SELECT oid FROM pg_type WHERE typname = 'txtidx'),
        true,
        (SELECT oid FROM pg_type WHERE typname = 'gtxtidx'));

SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE txtidx_ops_tmp
FROM pg_operator o, pg_type t, pg_type tq
WHERE o.oprleft = t.oid and o.oprright=tq.oid
   and t.typname = 'txtidx'
   and ( tq.typname='query_txt' or tq.typname='mquery_txt' );

INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
   SELECT opcl.oid, 1, false, c.opoid
   FROM pg_opclass opcl, txtidx_ops_tmp c
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and c.oprname = '@@';

INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
   SELECT opcl.oid, 2, false, c.opoid
   FROM pg_opclass opcl, txtidx_ops_tmp c
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and c.oprname = '##';

DROP TABLE txtidx_ops_tmp;

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 1, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_consistent';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 2, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_union';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 3, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_compress';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 4, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_decompress';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 5, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_penalty';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 6, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_picksplit';

INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
   SELECT opcl.oid, 7, pro.oid
   FROM pg_opclass opcl, pg_proc pro
   WHERE
      opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
      and opcname = 'gist_txtidx_ops'
      and proname = 'gtxtidx_same';



END TRANSACTION;
