-- Create the user-defined type for N-dimensional boxes -- BEGIN TRANSACTION; CREATE FUNCTION cube_in(opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION cube_out(opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE TYPE cube ( internallength = variable, input = cube_in, output = cube_out ); COMMENT ON TYPE cube IS 'multi-dimensional cube ''(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)'''; -- -- External C-functions for R-tree methods -- -- Left/Right methods CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_over_left(cube, cube) IS 'is over and left of (NOT IMPLEMENTED)'; CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_over_right(cube, cube) IS 'is over and right of (NOT IMPLEMENTED)'; CREATE FUNCTION cube_left(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_left(cube, cube) IS 'is left of (NOT IMPLEMENTED)'; CREATE FUNCTION cube_right(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_right(cube, cube) IS 'is right of (NOT IMPLEMENTED)'; -- Comparison methods CREATE FUNCTION cube_lt(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_lt(cube, cube) IS 'lower than'; CREATE FUNCTION cube_gt(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_gt(cube, cube) IS 'greater than'; CREATE FUNCTION cube_contains(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_contains(cube, cube) IS 'contains'; CREATE FUNCTION cube_contained(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_contained(cube, cube) IS 'contained in'; CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_overlap(cube, cube) IS 'overlaps'; CREATE FUNCTION cube_same(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_same(cube, cube) IS 'same as'; CREATE FUNCTION cube_different(cube, cube) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); COMMENT ON FUNCTION cube_different(cube, cube) IS 'different'; -- support routines for indexing CREATE FUNCTION cube_union(cube, cube) RETURNS cube AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); CREATE FUNCTION cube_inter(cube, cube) RETURNS cube AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); CREATE FUNCTION cube_size(cube) RETURNS float4 AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); -- Misc N-dimensional functions -- proximity routines CREATE FUNCTION cube_distance(cube, cube) RETURNS float4 AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); -- -- OPERATORS -- CREATE OPERATOR < ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_lt, COMMUTATOR = '>', RESTRICT = scalarltsel, JOIN = scalarltjoinsel ); CREATE OPERATOR > ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_gt, COMMUTATOR = '<', RESTRICT = scalargtsel, JOIN = scalargtjoinsel ); CREATE OPERATOR << ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_left, COMMUTATOR = '>>', RESTRICT = positionsel, JOIN = positionjoinsel ); CREATE OPERATOR &< ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_over_left, COMMUTATOR = '&>', RESTRICT = positionsel, JOIN = positionjoinsel ); CREATE OPERATOR && ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_overlap, COMMUTATOR = '&&', RESTRICT = positionsel, JOIN = positionjoinsel ); CREATE OPERATOR &> ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_over_right, COMMUTATOR = '&<', RESTRICT = positionsel, JOIN = positionjoinsel ); CREATE OPERATOR >> ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_right, COMMUTATOR = '<<', RESTRICT = positionsel, JOIN = positionjoinsel ); CREATE OPERATOR = ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_same, COMMUTATOR = '=', NEGATOR = '<>', RESTRICT = eqsel, JOIN = eqjoinsel, SORT1 = '<', SORT2 = '<' ); CREATE OPERATOR <> ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_different, COMMUTATOR = '<>', NEGATOR = '=', RESTRICT = neqsel, JOIN = neqjoinsel ); CREATE OPERATOR @ ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_contains, COMMUTATOR = '~', RESTRICT = contsel, JOIN = contjoinsel ); CREATE OPERATOR ~ ( LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_contained, COMMUTATOR = '@', RESTRICT = contsel, JOIN = contjoinsel ); -- define the GiST support methods CREATE FUNCTION g_cube_consistent(opaque,cube,int4) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION g_cube_compress(opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION g_cube_decompress(opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION g_cube_penalty(opaque,opaque,opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); CREATE FUNCTION g_cube_picksplit(opaque, opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION g_cube_union(bytea, opaque) RETURNS cube AS 'MODULE_PATHNAME' LANGUAGE 'c'; CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; -- register the default opclass for indexing INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_cube_ops', (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'cube'), true, 0); -- get the comparators for boxes and store them in a tmp table SELECT o.oid AS opoid, o.oprname INTO TEMP TABLE gist_cube_ops_tmp FROM pg_operator o, pg_type t WHERE o.oprleft = t.oid and o.oprright = t.oid and t.typname = 'cube'; -- make sure we have the right operators -- SELECT * from gist_cube_ops_tmp; -- using the tmp table, generate the amop entries -- cube_left INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 1, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '<<'; -- cube_over_left INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 2, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '&<'; -- cube_overlap INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 3, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '&&'; -- cube_over_right INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 4, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '&>'; -- cube_right INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 5, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '>>'; -- cube_same INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 6, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '='; -- cube_contains INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 7, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '@'; -- cube_contained INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) SELECT opcl.oid, 8, false, c.opoid FROM pg_opclass opcl, gist_cube_ops_tmp c WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_cube_ops' and c.oprname = '~'; DROP TABLE gist_cube_ops_tmp; -- add the entries to amproc for the support methods -- note the amprocnum numbers associated with each are specific! 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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_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_cube_ops' and proname = 'g_cube_same'; END TRANSACTION;