f933766ba7
pgsql-hackers. pg_opclass now has a row for each opclass supported by each index AM, not a row for each opclass name. This allows pg_opclass to show directly whether an AM supports an opclass, and furthermore makes it possible to store additional information about an opclass that might be AM-dependent. pg_opclass and pg_amop now store "lossy" and "haskeytype" information that we previously expected the user to remember to provide in CREATE INDEX commands. Lossiness is no longer an index-level property, but is associated with the use of a particular operator in a particular index opclass. Along the way, IndexSupportInitialize now uses the syscaches to retrieve pg_amop and pg_amproc entries. I find this reduces backend launch time by about ten percent, at the cost of a couple more special cases in catcache.c's IndexScanOK. Initial work by Oleg Bartunov and Teodor Sigaev, further hacking by Tom Lane. initdb forced.
371 lines
10 KiB
MySQL
371 lines
10 KiB
MySQL
-- 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, opcintype, opcdefault, opckeytype)
|
|
VALUES (
|
|
(SELECT oid FROM pg_am WHERE amname = 'gist'),
|
|
'gist_cube_ops',
|
|
(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;
|