Commit f933766b authored by Tom Lane's avatar Tom Lane

Restructure pg_opclass, pg_amop, and pg_amproc per previous discussions in

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.
parent c2d15669
...@@ -212,15 +212,18 @@ CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque ...@@ -212,15 +212,18 @@ CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque
-- register the default opclass for indexing -- register the default opclass for indexing
INSERT INTO pg_opclass (opcname, opcdeftype) INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
SELECT 'gist_cube_ops', oid VALUES (
FROM pg_type (SELECT oid FROM pg_am WHERE amname = 'gist'),
WHERE typname = 'cube'; '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 -- get the comparators for boxes and store them in a tmp table
SELECT o.oid AS opoid, o.oprname SELECT o.oid AS opoid, o.oprname
INTO TABLE gist_cube_ops_tmp INTO TEMP TABLE gist_cube_ops_tmp
FROM pg_operator o, pg_type t FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'cube'; and t.typname = 'cube';
...@@ -231,59 +234,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid ...@@ -231,59 +234,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid
-- using the tmp table, generate the amop entries -- using the tmp table, generate the amop entries
-- cube_left -- cube_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 1 SELECT opcl.oid, 1, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '<<'; and c.oprname = '<<';
-- cube_over_left -- cube_over_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 2 SELECT opcl.oid, 2, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&<'; and c.oprname = '&<';
-- cube_overlap -- cube_overlap
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 3 SELECT opcl.oid, 3, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&&'; and c.oprname = '&&';
-- cube_over_right -- cube_over_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 4 SELECT opcl.oid, 4, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&>'; and c.oprname = '&>';
-- cube_right -- cube_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 5 SELECT opcl.oid, 5, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '>>'; and c.oprname = '>>';
-- cube_same -- cube_same
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 6 SELECT opcl.oid, 6, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '='; and c.oprname = '=';
-- cube_contains -- cube_contains
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 7 SELECT opcl.oid, 7, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '@'; and c.oprname = '@';
-- cube_contained -- cube_contained
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 8 SELECT opcl.oid, 8, false, c.opoid
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '~'; and c.oprname = '~';
DROP TABLE gist_cube_ops_tmp; DROP TABLE gist_cube_ops_tmp;
...@@ -292,46 +311,60 @@ DROP TABLE gist_cube_ops_tmp; ...@@ -292,46 +311,60 @@ DROP TABLE gist_cube_ops_tmp;
-- add the entries to amproc for the support methods -- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific! -- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 1 SELECT opcl.oid, 1, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_consistent'; and proname = 'g_cube_consistent';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 2 SELECT opcl.oid, 2, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_union'; and proname = 'g_cube_union';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 3 SELECT opcl.oid, 3, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_compress'; and proname = 'g_cube_compress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 4 SELECT opcl.oid, 4, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_decompress'; and proname = 'g_cube_decompress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 5 SELECT opcl.oid, 5, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_penalty'; and proname = 'g_cube_penalty';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 6 SELECT opcl.oid, 6, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_picksplit'; and proname = 'g_cube_picksplit';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 7 SELECT opcl.oid, 7, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_same'; and proname = 'g_cube_same';
END TRANSACTION; END TRANSACTION;
...@@ -48,10 +48,8 @@ Join pg_am.amrestrpos => pg_proc.oid ...@@ -48,10 +48,8 @@ Join pg_am.amrestrpos => pg_proc.oid
Join pg_am.ambuild => pg_proc.oid Join pg_am.ambuild => pg_proc.oid
Join pg_am.ambulkdelete => pg_proc.oid Join pg_am.ambulkdelete => pg_proc.oid
Join pg_am.amcostestimate => pg_proc.oid Join pg_am.amcostestimate => pg_proc.oid
Join pg_amop.amopid => pg_am.oid
Join pg_amop.amopclaid => pg_opclass.oid Join pg_amop.amopclaid => pg_opclass.oid
Join pg_amop.amopopr => pg_operator.oid Join pg_amop.amopopr => pg_operator.oid
Join pg_amproc.amid => pg_am.oid
Join pg_amproc.amopclaid => pg_opclass.oid Join pg_amproc.amopclaid => pg_opclass.oid
Join pg_amproc.amproc => pg_proc.oid Join pg_amproc.amproc => pg_proc.oid
Join pg_attribute.attrelid => pg_class.oid Join pg_attribute.attrelid => pg_class.oid
...@@ -63,7 +61,8 @@ Join pg_class.reltoastidxid => pg_class.oid ...@@ -63,7 +61,8 @@ Join pg_class.reltoastidxid => pg_class.oid
Join pg_description.classoid => pg_class.oid Join pg_description.classoid => pg_class.oid
Join pg_index.indexrelid => pg_class.oid Join pg_index.indexrelid => pg_class.oid
Join pg_index.indrelid => pg_class.oid Join pg_index.indrelid => pg_class.oid
Join pg_opclass.opcdeftype => pg_type.oid Join pg_opclass.opcamid => pg_am.oid
Join pg_opclass.opcintype => pg_type.oid
Join pg_operator.oprleft => pg_type.oid Join pg_operator.oprleft => pg_type.oid
Join pg_operator.oprright => pg_type.oid Join pg_operator.oprright => pg_type.oid
Join pg_operator.oprresult => pg_type.oid Join pg_operator.oprresult => pg_type.oid
......
...@@ -68,15 +68,17 @@ main(int argc, char **argv) ...@@ -68,15 +68,17 @@ main(int argc, char **argv)
if (strcmp(typname, "oid") == 0) if (strcmp(typname, "oid") == 0)
sprintf(query, "\ sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \ DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \ SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \ FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.\"%s\" = t2.oid ", relname, relname2, attname); WHERE t1.\"%s\" = t2.oid ",
relname, relname2, attname);
else else
sprintf(query, "\ sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \ DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \ SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \ FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.\"%s\") = t2.oid ", relname, relname2, attname); WHERE RegprocToOid(t1.\"%s\") = t2.oid ",
relname, relname2, attname);
doquery(query); doquery(query);
doquery("FETCH ALL IN c_matches"); doquery("FETCH ALL IN c_matches");
......
This is an implementation of RD-tree data structure using GiST interface This is an implementation of RD-tree data structure using GiST interface
of PostgreSQL. It has built-in lossy compression - must be declared of PostgreSQL. It has built-in lossy compression.
in index creation - with (islossy). Current implementation provides index
support for one-dimensional array of int4's - gist__int_ops, suitable for Current implementation provides index support for one-dimensional array of
small and medium size of arrays (used on default), and gist__intbig_ops for int4's - gist__int_ops, suitable for small and medium size of arrays (used on
indexing large arrays (we use superimposed signature with length of 4096 default), and gist__intbig_ops for indexing large arrays (we use superimposed
bits to represent sets). signature with length of 4096 bits to represent sets).
All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov
(oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist (oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
...@@ -35,7 +35,7 @@ EXAMPLE USAGE: ...@@ -35,7 +35,7 @@ EXAMPLE USAGE:
-- create indices -- create indices
CREATE unique index message_key on message ( mid ); CREATE unique index message_key on message ( mid );
CREATE unique index message_section_map_key2 on message_section_map (sid, mid ); CREATE unique index message_section_map_key2 on message_section_map (sid, mid );
CREATE INDEX message_rdtree_idx on message using gist ( sections gist__int_ops) with ( islossy ); CREATE INDEX message_rdtree_idx on message using gist ( sections gist__int_ops);
-- select some messages with section in 1 OR 2 - OVERLAP operator -- select some messages with section in 1 OR 2 - OVERLAP operator
select message.mid from message where message.sections && '{1,2}'; select message.mid from message where message.sections && '{1,2}';
......
This diff is collapsed.
...@@ -49,7 +49,7 @@ print <<EOT; ...@@ -49,7 +49,7 @@ print <<EOT;
CREATE unique index message_key on message ( mid ); CREATE unique index message_key on message ( mid );
--CREATE unique index message_section_map_key1 on message_section_map ( mid, sid ); --CREATE unique index message_section_map_key1 on message_section_map ( mid, sid );
CREATE unique index message_section_map_key2 on message_section_map ( sid, mid ); CREATE unique index message_section_map_key2 on message_section_map ( sid, mid );
CREATE INDEX message_rdtree_idx on message using gist ( sections gist__int_ops ) with ( islossy ); CREATE INDEX message_rdtree_idx on message using gist ( sections gist__int_ops );
VACUUM ANALYZE; VACUUM ANALYZE;
select count(*) from message; select count(*) from message;
......
...@@ -17,7 +17,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}'; ...@@ -17,7 +17,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}';
12 12
(1 row) (1 row)
CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ) with ( islossy ); CREATE INDEX text_idx on test__int using gist ( a gist__int_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
count count
------- -------
...@@ -31,7 +31,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}'; ...@@ -31,7 +31,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}';
(1 row) (1 row)
drop index text_idx; drop index text_idx;
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ) with ( islossy ); CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
count count
------- -------
......
...@@ -13,13 +13,13 @@ CREATE TABLE test__int( a int[] ); ...@@ -13,13 +13,13 @@ CREATE TABLE test__int( a int[] );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ) with ( islossy ); CREATE INDEX text_idx on test__int using gist ( a gist__int_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
drop index text_idx; drop index text_idx;
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ) with ( islossy ); CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
SELECT count(*) from test__int WHERE a && '{23,50}'; SELECT count(*) from test__int WHERE a && '{23,50}';
SELECT count(*) from test__int WHERE a @ '{23,50}'; SELECT count(*) from test__int WHERE a @ '{23,50}';
......
...@@ -36,7 +36,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; ...@@ -36,7 +36,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
(1 row) (1 row)
drop index pix; drop index pix;
create index pix on polytmp using gist (p gist_poly_ops) with(islossy); create index pix on polytmp using gist (p gist_poly_ops);
select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
count count
------- -------
......
This diff is collapsed.
...@@ -32,7 +32,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; ...@@ -32,7 +32,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
drop index pix; drop index pix;
create index pix on polytmp using gist (p gist_poly_ops) with(islossy); create index pix on polytmp using gist (p gist_poly_ops);
select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
...@@ -236,15 +236,18 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque ...@@ -236,15 +236,18 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque
-- register the default opclass for indexing -- register the default opclass for indexing
INSERT INTO pg_opclass (opcname, opcdeftype) INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
SELECT 'gist_seg_ops', oid VALUES (
FROM pg_type (SELECT oid FROM pg_am WHERE amname = 'gist'),
WHERE typname = 'seg'; 'gist_seg_ops',
(SELECT oid FROM pg_type WHERE typname = 'seg'),
true,
0);
-- get the comparators for segments and store them in a tmp table -- get the comparators for segments and store them in a tmp table
SELECT o.oid AS opoid, o.oprname SELECT o.oid AS opoid, o.oprname
INTO TABLE seg_ops_tmp INTO TEMP TABLE seg_ops_tmp
FROM pg_operator o, pg_type t FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'seg'; and t.typname = 'seg';
...@@ -255,59 +258,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid ...@@ -255,59 +258,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid
-- using the tmp table, generate the amop entries -- using the tmp table, generate the amop entries
-- seg_left -- seg_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 1 SELECT opcl.oid, 1, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '<<'; and c.oprname = '<<';
-- seg_overleft -- seg_overleft
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 2 SELECT opcl.oid, 2, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&<'; and c.oprname = '&<';
-- seg_overlap -- seg_overlap
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 3 SELECT opcl.oid, 3, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&&'; and c.oprname = '&&';
-- seg_overright -- seg_overright
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 4 SELECT opcl.oid, 4, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&>'; and c.oprname = '&>';
-- seg_right -- seg_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 5 SELECT opcl.oid, 5, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '>>'; and c.oprname = '>>';
-- seg_same -- seg_same
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 6 SELECT opcl.oid, 6, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '='; and c.oprname = '=';
-- seg_contains -- seg_contains
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 7 SELECT opcl.oid, 7, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '@'; and c.oprname = '@';
-- seg_contained -- seg_contained
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy) INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT am.oid, opcl.oid, c.opoid, 8 SELECT opcl.oid, 8, false, c.opoid
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c FROM pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '~'; and c.oprname = '~';
DROP TABLE seg_ops_tmp; DROP TABLE seg_ops_tmp;
...@@ -316,46 +335,60 @@ DROP TABLE seg_ops_tmp; ...@@ -316,46 +335,60 @@ DROP TABLE seg_ops_tmp;
-- add the entries to amproc for the support methods -- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific! -- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 1 SELECT opcl.oid, 1, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_consistent'; and proname = 'gseg_consistent';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 2 SELECT opcl.oid, 2, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_union'; and proname = 'gseg_union';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 3 SELECT opcl.oid, 3, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_compress'; and proname = 'gseg_compress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 4 SELECT opcl.oid, 4, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_decompress'; and proname = 'gseg_decompress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 5 SELECT opcl.oid, 5, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_penalty'; and proname = 'gseg_penalty';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 6 SELECT opcl.oid, 6, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_picksplit'; and proname = 'gseg_picksplit';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT am.oid, opcl.oid, pro.oid, 7 SELECT opcl.oid, 7, pro.oid
FROM pg_am am, pg_opclass opcl, pg_proc pro FROM pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops' WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_same'; and proname = 'gseg_same';
END TRANSACTION; END TRANSACTION;
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.20 2001/08/10 18:57:32 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.21 2001/08/21 16:35:58 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
...@@ -1050,13 +1050,6 @@ ...@@ -1050,13 +1050,6 @@
<entry>unused</entry> <entry>unused</entry>
</row> </row>
<row>
<entry>indislossy</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>???</entry>
</row>
<row> <row>
<entry>indisunique</entry> <entry>indisunique</entry>
<entry><type>bool</type></entry> <entry><type>bool</type></entry>
......
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.20 2001/07/16 05:06:57 tgl Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.21 2001/08/21 16:35:59 tgl Exp $ -->
<chapter id="indexes"> <chapter id="indexes">
<title id="indexes-title">Indexes</title> <title id="indexes-title">Indexes</title>
...@@ -401,15 +401,14 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> ...@@ -401,15 +401,14 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
<para> <para>
The following query shows all defined operator classes: The following query shows all defined operator classes:
<programlisting> <programlisting>
SELECT am.amname AS acc_name, SELECT am.amname AS acc_method,
opc.opcname AS ops_name, opc.opcname AS ops_name,
opr.oprname AS ops_comp opr.oprname AS ops_comp
FROM pg_am am, pg_amop amop, FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr
pg_opclass opc, pg_operator opr WHERE opc.opcamid = am.oid AND
WHERE amop.amopid = am.oid AND
amop.amopclaid = opc.oid AND amop.amopclaid = opc.oid AND
amop.amopopr = opr.oid amop.amopopr = opr.oid
ORDER BY acc_name, ops_name, ops_comp; ORDER BY acc_method, ops_name, ops_comp
</programlisting> </programlisting>
</para> </para>
</sect1> </sect1>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_index.sgml,v 1.21 2001/08/06 18:09:45 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_index.sgml,v 1.22 2001/08/21 16:35:59 tgl Exp $
Postgres documentation Postgres documentation
--> -->
...@@ -374,9 +374,8 @@ ERROR: Cannot create index: 'index_name' already exists. ...@@ -374,9 +374,8 @@ ERROR: Cannot create index: 'index_name' already exists.
SELECT am.amname AS acc_method, SELECT am.amname AS acc_method,
opc.opcname AS ops_name, opc.opcname AS ops_name,
opr.oprname AS ops_comp opr.oprname AS ops_comp
FROM pg_am am, pg_amop amop, FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr
pg_opclass opc, pg_operator opr WHERE opc.opcamid = am.oid AND
WHERE amop.amopid = am.oid AND
amop.amopclaid = opc.oid AND amop.amopclaid = opc.oid AND
amop.amopopr = opr.oid amop.amopopr = opr.oid
ORDER BY acc_method, ops_name, ops_comp ORDER BY acc_method, ops_name, ops_comp
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.81 2001/08/10 14:34:28 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.82 2001/08/21 16:35:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_opclass.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "access/xlogutils.h" #include "access/xlogutils.h"
...@@ -1377,10 +1379,9 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ ...@@ -1377,10 +1379,9 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i)) for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i))
{ {
IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
sum_grow=0; sum_grow=0;
for (j=0; j<r->rd_att->natts; j++) { for (j=0; j<r->rd_att->natts; j++) {
IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
datum = index_getattr(itup, j+1, r->rd_att, &IsNull); datum = index_getattr(itup, j+1, r->rd_att, &IsNull);
gistdentryinit(giststate, j, &entry, datum, r, p, i, ATTSIZE( datum, r, j+1, IsNull ), FALSE, IsNull); gistdentryinit(giststate, j, &entry, datum, r, p, i, ATTSIZE( datum, r, j+1, IsNull ), FALSE, IsNull);
gistpenalty( giststate, j, &entry, IsNull, &identry[j], isnull[j], &usize); gistpenalty( giststate, j, &entry, IsNull, &identry[j], isnull[j], &usize);
...@@ -1548,20 +1549,32 @@ initGISTstate(GISTSTATE *giststate, Relation index) ...@@ -1548,20 +1549,32 @@ initGISTstate(GISTSTATE *giststate, Relation index)
RegProcedure consistent_proc, RegProcedure consistent_proc,
union_proc, union_proc,
compress_proc, compress_proc,
decompress_proc; decompress_proc,
RegProcedure penalty_proc, penalty_proc,
picksplit_proc, picksplit_proc,
equal_proc; equal_proc;
HeapTuple htup; HeapTuple itup;
HeapTuple ctup;
Form_pg_index itupform; Form_pg_index itupform;
Oid indexrelid; Form_pg_opclass opclassform;
Oid inputtype;
Oid keytype;
int i; int i;
if (index->rd_att->natts >= INDEX_MAX_KEYS) if (index->rd_att->natts > INDEX_MAX_KEYS)
elog(ERROR, "initGISTstate: numberOfAttributes %d > %d", elog(ERROR, "initGISTstate: numberOfAttributes %d > %d",
index->rd_att->natts, INDEX_MAX_KEYS); index->rd_att->natts, INDEX_MAX_KEYS);
itup = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(index)),
0, 0, 0);
if (!HeapTupleIsValid(itup))
elog(ERROR, "initGISTstate: index %u not found",
RelationGetRelid(index));
itupform = (Form_pg_index) GETSTRUCT(itup);
for(i=0; i<index->rd_att->natts; i++) { for (i = 0; i < index->rd_att->natts; i++)
{
consistent_proc = index_getprocid(index, i+1, GIST_CONSISTENT_PROC ); consistent_proc = index_getprocid(index, i+1, GIST_CONSISTENT_PROC );
union_proc = index_getprocid(index, i+1, GIST_UNION_PROC ); union_proc = index_getprocid(index, i+1, GIST_UNION_PROC );
compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC ); compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC );
...@@ -1577,37 +1590,35 @@ initGISTstate(GISTSTATE *giststate, Relation index) ...@@ -1577,37 +1590,35 @@ initGISTstate(GISTSTATE *giststate, Relation index)
fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) ); fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) );
fmgr_info(equal_proc, &((giststate->equalFn)[i]) ); fmgr_info(equal_proc, &((giststate->equalFn)[i]) );
giststate->attbyval[i] = /* Check opclass entry to see if there is a keytype */
index->rd_att->attrs[i]->attbyval; ctup = SearchSysCache(CLAOID,
ObjectIdGetDatum(itupform->indclass[i]),
0, 0, 0);
if (!HeapTupleIsValid(ctup))
elog(ERROR, "cache lookup failed for opclass %u",
itupform->indclass[i]);
opclassform = (Form_pg_opclass) GETSTRUCT(ctup);
inputtype = opclassform->opcintype;
keytype = opclassform->opckeytype;
ReleaseSysCache(ctup);
if (OidIsValid(keytype))
{
/* index column type is (possibly) different from input data */
giststate->haskeytype[i] = true;
giststate->attbyval[i] = get_typbyval(inputtype);
giststate->keytypbyval[i] = index->rd_att->attrs[i]->attbyval;
}
else
{
/* Normal case where index column type is same as input data */
giststate->haskeytype[i] = false;
giststate->attbyval[i] = index->rd_att->attrs[i]->attbyval;
giststate->keytypbyval[i] = false; /* not actually used */
}
} }
/* see if key type is different from type of attribute being indexed */ ReleaseSysCache(itup);
htup = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(index)),
0, 0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "initGISTstate: index %u not found",
RelationGetRelid(index));
itupform = (Form_pg_index) GETSTRUCT(htup);
giststate->haskeytype = itupform->indhaskeytype;
indexrelid = itupform->indexrelid;
ReleaseSysCache(htup);
if (giststate->haskeytype)
{
/* key type is different -- is it byval? */
htup = SearchSysCache(ATTNUM,
ObjectIdGetDatum(indexrelid),
UInt16GetDatum(FirstOffsetNumber),
0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "initGISTstate: no attribute tuple %u %d",
indexrelid, FirstOffsetNumber);
giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval);
ReleaseSysCache(htup);
}
else
giststate->keytypbyval = FALSE;
} }
#ifdef GIST_PAGEADDITEM #ifdef GIST_PAGEADDITEM
...@@ -1670,7 +1681,7 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, ...@@ -1670,7 +1681,7 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
GISTENTRY *dep; GISTENTRY *dep;
gistentryinit(*e, k, r, pg, o, b, l); gistentryinit(*e, k, r, pg, o, b, l);
if (giststate->haskeytype) if (giststate->haskeytype[nkey])
{ {
if ( b && ! isNull ) { if ( b && ! isNull ) {
dep = (GISTENTRY *) dep = (GISTENTRY *)
...@@ -1698,7 +1709,7 @@ gistcentryinit(GISTSTATE *giststate, int nkey, ...@@ -1698,7 +1709,7 @@ gistcentryinit(GISTSTATE *giststate, int nkey,
GISTENTRY *cep; GISTENTRY *cep;
gistentryinit(*e, k, r, pg, o, b, l); gistentryinit(*e, k, r, pg, o, b, l);
if (giststate->haskeytype) if (giststate->haskeytype[nkey])
{ {
if ( ! isNull ) { if ( ! isNull ) {
cep = (GISTENTRY *) cep = (GISTENTRY *)
...@@ -1792,7 +1803,7 @@ gistpenalty( GISTSTATE *giststate, int attno, ...@@ -1792,7 +1803,7 @@ gistpenalty( GISTSTATE *giststate, int attno,
FunctionCall3(&giststate->penaltyFn[attno], FunctionCall3(&giststate->penaltyFn[attno],
PointerGetDatum(key1), PointerGetDatum(key1),
PointerGetDatum(key2), PointerGetDatum(key2),
PointerGetDatum(&penalty)); PointerGetDatum(penalty));
} }
#ifdef GISTDEBUG #ifdef GISTDEBUG
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.51 2001/06/01 02:41:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.52 2001/08/21 16:36:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -457,61 +457,32 @@ RelationInvokeStrategy(Relation relation, ...@@ -457,61 +457,32 @@ RelationInvokeStrategy(Relation relation,
#endif #endif
/* ---------------- /* ----------------
* OperatorRelationFillScanKeyEntry * FillScanKeyEntry
* *
* Initialize a ScanKey entry given already-opened pg_operator relation. * Initialize a ScanKey entry for the given operator OID.
* ---------------- * ----------------
*/ */
static void static void
OperatorRelationFillScanKeyEntry(Relation operatorRelation, FillScanKeyEntry(Oid operatorObjectId, ScanKey entry)
Oid operatorObjectId,
ScanKey entry)
{ {
HeapTuple tuple; HeapTuple tuple;
HeapScanDesc scan = NULL;
bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
if (cachesearch) tuple = SearchSysCache(OPEROID,
{ ObjectIdGetDatum(operatorObjectId),
tuple = SearchSysCache(OPEROID, 0, 0, 0);
ObjectIdGetDatum(operatorObjectId),
0, 0, 0);
}
else
{
ScanKeyData scanKeyData;
ScanKeyEntryInitialize(&scanKeyData, 0,
ObjectIdAttributeNumber,
F_OIDEQ,
ObjectIdGetDatum(operatorObjectId));
scan = heap_beginscan(operatorRelation, false, SnapshotNow,
1, &scanKeyData);
tuple = heap_getnext(scan, 0);
}
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ elog(ERROR, "FillScanKeyEntry: unknown operator %u",
if (!cachesearch)
heap_endscan(scan);
elog(ERROR, "OperatorRelationFillScanKeyEntry: unknown operator %u",
operatorObjectId); operatorObjectId);
}
MemSet(entry, 0, sizeof(*entry)); MemSet(entry, 0, sizeof(*entry));
entry->sk_flags = 0; entry->sk_flags = 0;
entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode; entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode;
if (cachesearch) ReleaseSysCache(tuple);
ReleaseSysCache(tuple);
else
heap_endscan(scan);
if (!RegProcedureIsValid(entry->sk_procedure)) if (!RegProcedureIsValid(entry->sk_procedure))
elog(ERROR, elog(ERROR, "FillScanKeyEntry: no procedure for operator %u",
"OperatorRelationFillScanKeyEntry: no procedure for operator %u",
operatorObjectId); operatorObjectId);
/* /*
...@@ -548,160 +519,99 @@ IndexSupportInitialize(IndexStrategy indexStrategy, ...@@ -548,160 +519,99 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
StrategyNumber maxSupportNumber, StrategyNumber maxSupportNumber,
AttrNumber maxAttributeNumber) AttrNumber maxAttributeNumber)
{ {
Relation relation = NULL;
HeapScanDesc scan = NULL;
ScanKeyData entry[2];
Relation operatorRelation;
HeapTuple tuple; HeapTuple tuple;
Form_pg_index iform; Form_pg_index iform;
StrategyMap map;
AttrNumber attNumber;
int attIndex; int attIndex;
Oid operatorClassObjectId[INDEX_MAX_KEYS]; Oid operatorClassObjectId[INDEX_MAX_KEYS];
bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
if (cachesearch)
{
tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexObjectId),
0, 0, 0);
}
else
{
ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
F_OIDEQ,
ObjectIdGetDatum(indexObjectId));
relation = heap_openr(IndexRelationName, AccessShareLock); maxStrategyNumber = AMStrategies(maxStrategyNumber);
scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
tuple = heap_getnext(scan, 0);
}
tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexObjectId),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "IndexSupportInitialize: no pg_index entry for index %u", elog(ERROR, "IndexSupportInitialize: no pg_index entry for index %u",
indexObjectId); indexObjectId);
iform = (Form_pg_index) GETSTRUCT(tuple); iform = (Form_pg_index) GETSTRUCT(tuple);
*isUnique = iform->indisunique; *isUnique = iform->indisunique;
maxStrategyNumber = AMStrategies(maxStrategyNumber);
/* /*
* XXX note that the following assumes the INDEX tuple is well formed * XXX note that the following assumes the INDEX tuple is well formed
* and that the *key and *class are 0 terminated. * and that the *key and *class are 0 terminated.
*/ */
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++) for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{ {
if (!OidIsValid(iform->indkey[attIndex])) if (iform->indkey[attIndex] == InvalidAttrNumber ||
{ !OidIsValid(iform->indclass[attIndex]))
if (attIndex == InvalidAttrNumber) elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
break;
}
operatorClassObjectId[attIndex] = iform->indclass[attIndex]; operatorClassObjectId[attIndex] = iform->indclass[attIndex];
} }
if (cachesearch) ReleaseSysCache(tuple);
ReleaseSysCache(tuple);
else
{
heap_endscan(scan);
heap_close(relation, AccessShareLock);
}
/* if support routines exist for this access method, load them */ /* if support routines exist for this access method, load them */
if (maxSupportNumber > 0) if (maxSupportNumber > 0)
{ {
ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid, for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
F_OIDEQ,
ObjectIdGetDatum(accessMethodObjectId));
ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
F_OIDEQ,
InvalidOid); /* will set below */
relation = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock);
for (attNumber = 1; attNumber <= maxAttributeNumber; attNumber++)
{ {
Oid opclass = operatorClassObjectId[attIndex];
RegProcedure *loc; RegProcedure *loc;
StrategyNumber support; StrategyNumber support;
loc = &indexSupport[((attNumber - 1) * maxSupportNumber)]; loc = &indexSupport[attIndex * maxSupportNumber];
for (support = 0; support < maxSupportNumber; ++support) for (support = 0; support < maxSupportNumber; ++support)
loc[support] = InvalidOid;
entry[1].sk_argument =
ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Form_pg_amproc aform; tuple = SearchSysCache(AMPROCNUM,
ObjectIdGetDatum(opclass),
aform = (Form_pg_amproc) GETSTRUCT(tuple); Int16GetDatum(support+1),
support = aform->amprocnum; 0, 0);
Assert(support > 0 && support <= maxSupportNumber); if (HeapTupleIsValid(tuple))
loc[support - 1] = aform->amproc; {
Form_pg_amproc amprocform;
amprocform = (Form_pg_amproc) GETSTRUCT(tuple);
loc[support] = amprocform->amproc;
ReleaseSysCache(tuple);
}
else
loc[support] = InvalidOid;
} }
heap_endscan(scan);
} }
heap_close(relation, AccessShareLock);
} }
/* Now load the strategy information for the index operators */ /* Now load the strategy information for the index operators */
ScanKeyEntryInitialize(&entry[0], 0, for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
Anum_pg_amop_amopid,
F_OIDEQ,
ObjectIdGetDatum(accessMethodObjectId));
ScanKeyEntryInitialize(&entry[1], 0,
Anum_pg_amop_amopclaid,
F_OIDEQ,
0); /* will fill below */
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
operatorRelation = heap_openr(OperatorRelationName, AccessShareLock);
for (attNumber = maxAttributeNumber; attNumber > 0; attNumber--)
{ {
Oid opclass = operatorClassObjectId[attIndex];
StrategyMap map;
StrategyNumber strategy; StrategyNumber strategy;
entry[1].sk_argument =
ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
map = IndexStrategyGetStrategyMap(indexStrategy, map = IndexStrategyGetStrategyMap(indexStrategy,
maxStrategyNumber, maxStrategyNumber,
attNumber); attIndex + 1);
for (strategy = 1; strategy <= maxStrategyNumber; strategy++) for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy)); {
ScanKey mapentry = StrategyMapGetScanKeyEntry(map, strategy);
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry); tuple = SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(opclass),
Int16GetDatum(strategy),
0, 0);
if (HeapTupleIsValid(tuple))
{
Form_pg_amop amopform;
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) amopform = (Form_pg_amop) GETSTRUCT(tuple);
{ FillScanKeyEntry(amopform->amopopr, mapentry);
Form_pg_amop aform; ReleaseSysCache(tuple);
}
aform = (Form_pg_amop) GETSTRUCT(tuple); else
strategy = aform->amopstrategy; ScanKeyEntrySetIllegal(mapentry);
Assert(strategy > 0 && strategy <= maxStrategyNumber);
OperatorRelationFillScanKeyEntry(operatorRelation,
aform->amopopr,
StrategyMapGetScanKeyEntry(map, strategy));
} }
heap_endscan(scan);
} }
heap_close(operatorRelation, AccessShareLock);
heap_close(relation, AccessShareLock);
} }
/* ---------------- /* ----------------
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.37 2001/08/10 18:57:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.38 2001/08/21 16:36:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -246,7 +246,7 @@ Boot_DeclareIndexStmt: ...@@ -246,7 +246,7 @@ Boot_DeclareIndexStmt:
DefineIndex(LexIDStr($5), DefineIndex(LexIDStr($5),
LexIDStr($3), LexIDStr($3),
LexIDStr($7), LexIDStr($7),
$9, NIL, 0, 0, 0, NIL); $9, false, false, NULL, NIL);
do_end(); do_end();
} }
; ;
...@@ -259,7 +259,7 @@ Boot_DeclareUniqueIndexStmt: ...@@ -259,7 +259,7 @@ Boot_DeclareUniqueIndexStmt:
DefineIndex(LexIDStr($6), DefineIndex(LexIDStr($6),
LexIDStr($4), LexIDStr($4),
LexIDStr($8), LexIDStr($8),
$10, NIL, 1, 0, 0, NIL); $10, true, false, NULL, NIL);
do_end(); do_end();
} }
; ;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.160 2001/08/17 23:50:00 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.161 2001/08/21 16:36:00 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -71,9 +71,9 @@ static void InitializeAttributeOids(Relation indexRelation, ...@@ -71,9 +71,9 @@ static void InitializeAttributeOids(Relation indexRelation,
int numatts, Oid indexoid); int numatts, Oid indexoid);
static void AppendAttributeTuples(Relation indexRelation, int numatts); static void AppendAttributeTuples(Relation indexRelation, int numatts);
static void UpdateIndexRelation(Oid indexoid, Oid heapoid, static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid *classOids, Oid *classOids,
bool islossy, bool primary); bool primary);
static Oid IndexGetRelation(Oid indexId); static Oid IndexGetRelation(Oid indexId);
static bool activate_index(Oid indexId, bool activate, bool inplace); static bool activate_index(Oid indexId, bool activate, bool inplace);
...@@ -495,7 +495,6 @@ UpdateIndexRelation(Oid indexoid, ...@@ -495,7 +495,6 @@ UpdateIndexRelation(Oid indexoid,
Oid heapoid, Oid heapoid,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid *classOids, Oid *classOids,
bool islossy,
bool primary) bool primary)
{ {
Form_pg_index indexForm; Form_pg_index indexForm;
...@@ -535,8 +534,6 @@ UpdateIndexRelation(Oid indexoid, ...@@ -535,8 +534,6 @@ UpdateIndexRelation(Oid indexoid,
indexForm->indrelid = heapoid; indexForm->indrelid = heapoid;
indexForm->indproc = indexInfo->ii_FuncOid; indexForm->indproc = indexInfo->ii_FuncOid;
indexForm->indisclustered = false; /* not used */ indexForm->indisclustered = false; /* not used */
indexForm->indislossy = islossy;
indexForm->indhaskeytype = true; /* used by GIST */
indexForm->indisunique = indexInfo->ii_Unique; indexForm->indisunique = indexInfo->ii_Unique;
indexForm->indisprimary = primary; indexForm->indisprimary = primary;
memcpy((char *) &indexForm->indpred, (char *) predText, predLen); memcpy((char *) &indexForm->indpred, (char *) predText, predLen);
...@@ -671,7 +668,6 @@ index_create(char *heapRelationName, ...@@ -671,7 +668,6 @@ index_create(char *heapRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid accessMethodObjectId, Oid accessMethodObjectId,
Oid *classObjectId, Oid *classObjectId,
bool islossy,
bool primary, bool primary,
bool allow_system_table_mods) bool allow_system_table_mods)
{ {
...@@ -779,7 +775,7 @@ index_create(char *heapRelationName, ...@@ -779,7 +775,7 @@ index_create(char *heapRelationName,
* ---------------- * ----------------
*/ */
UpdateIndexRelation(indexoid, heapoid, indexInfo, UpdateIndexRelation(indexoid, heapoid, indexInfo,
classObjectId, islossy, primary); classObjectId, primary);
/* /*
* initialize the index strategy * initialize the index strategy
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.81 2001/08/10 18:57:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.82 2001/08/21 16:36:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -36,9 +36,9 @@ char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] = ...@@ -36,9 +36,9 @@ char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
char *Name_pg_am_indices[Num_pg_am_indices] = char *Name_pg_am_indices[Num_pg_am_indices] =
{AmNameIndex, AmOidIndex}; {AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] = char *Name_pg_amop_indices[Num_pg_amop_indices] =
{AccessMethodOpidIndex, AccessMethodStrategyIndex}; {AccessMethodOperatorIndex, AccessMethodStrategyIndex};
char *Name_pg_amproc_indices[Num_pg_amproc_indices] = char *Name_pg_amproc_indices[Num_pg_amproc_indices] =
{AccessProcedureIndex}; {AccessMethodProcedureIndex};
char *Name_pg_attr_indices[Num_pg_attr_indices] = char *Name_pg_attr_indices[Num_pg_attr_indices] =
{AttributeRelidNameIndex, AttributeRelidNumIndex}; {AttributeRelidNameIndex, AttributeRelidNumIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
...@@ -58,7 +58,7 @@ char *Name_pg_language_indices[Num_pg_language_indices] = ...@@ -58,7 +58,7 @@ char *Name_pg_language_indices[Num_pg_language_indices] =
char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] = char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
{LargeObjectLOidPNIndex}; {LargeObjectLOidPNIndex};
char *Name_pg_opclass_indices[Num_pg_opclass_indices] = char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
{OpclassDeftypeIndex, OpclassNameIndex, OpclassOidIndex}; {OpclassAmNameIndex, OpclassOidIndex};
char *Name_pg_operator_indices[Num_pg_operator_indices] = char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameIndex}; {OperatorOidIndex, OperatorNameIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] = char *Name_pg_proc_indices[Num_pg_proc_indices] =
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.68 2001/08/10 18:57:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.69 2001/08/21 16:36:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -225,7 +225,6 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) ...@@ -225,7 +225,6 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
indexInfo, indexInfo,
Old_pg_index_relation_Form->relam, Old_pg_index_relation_Form->relam,
Old_pg_index_Form->indclass, Old_pg_index_Form->indclass,
Old_pg_index_Form->indislossy,
Old_pg_index_Form->indisprimary, Old_pg_index_Form->indisprimary,
allowSystemTableMods); allowSystemTableMods);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.140 2001/08/10 18:57:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.141 2001/08/21 16:36:01 tgl Exp $
* *
* NOTES * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -1902,12 +1902,12 @@ AlterTableCreateToastTable(const char *relationName, bool silent) ...@@ -1902,12 +1902,12 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
indexInfo->ii_FuncOid = InvalidOid; indexInfo->ii_FuncOid = InvalidOid;
indexInfo->ii_Unique = true; indexInfo->ii_Unique = true;
classObjectId[0] = OID_OPS_OID; classObjectId[0] = OID_BTREE_OPS_OID;
classObjectId[1] = INT4_OPS_OID; classObjectId[1] = INT4_BTREE_OPS_OID;
toast_idxid = index_create(toast_relname, toast_idxname, indexInfo, toast_idxid = index_create(toast_relname, toast_idxname, indexInfo,
BTREE_AM_OID, classObjectId, BTREE_AM_OID, classObjectId,
false, true, true); true, true);
/* /*
* Update toast rel's pg_class entry to show that it has an index. * Update toast rel's pg_class entry to show that it has an index.
......
...@@ -8,26 +8,19 @@ ...@@ -8,26 +8,19 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.56 2001/08/10 18:57:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.57 2001/08/21 16:36:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_database.h"
#include "catalog/pg_index.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
...@@ -36,7 +29,6 @@ ...@@ -36,7 +29,6 @@
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
...@@ -57,7 +49,7 @@ static void NormIndexAttrs(IndexInfo *indexInfo, Oid *classOidP, ...@@ -57,7 +49,7 @@ static void NormIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
char *accessMethodName, Oid accessMethodId); char *accessMethodName, Oid accessMethodId);
static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType, static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId); char *accessMethodName, Oid accessMethodId);
static char *GetDefaultOpClass(Oid atttypid); static Oid GetDefaultOpClass(Oid attrType, Oid accessMethodId);
/* /*
* DefineIndex * DefineIndex
...@@ -65,16 +57,14 @@ static char *GetDefaultOpClass(Oid atttypid); ...@@ -65,16 +57,14 @@ static char *GetDefaultOpClass(Oid atttypid);
* *
* 'attributeList' is a list of IndexElem specifying either a functional * 'attributeList' is a list of IndexElem specifying either a functional
* index or a list of attributes to index on. * index or a list of attributes to index on.
* 'parameterList' is a list of DefElem specified in the with clause.
* 'predicate' is the qual specified in the where clause. * 'predicate' is the qual specified in the where clause.
* 'rangetable' is needed to interpret the predicate * 'rangetable' is needed to interpret the predicate.
*/ */
void void
DefineIndex(char *heapRelationName, DefineIndex(char *heapRelationName,
char *indexRelationName, char *indexRelationName,
char *accessMethodName, char *accessMethodName,
List *attributeList, List *attributeList,
List *parameterList,
bool unique, bool unique,
bool primary, bool primary,
Expr *predicate, Expr *predicate,
...@@ -88,8 +78,6 @@ DefineIndex(char *heapRelationName, ...@@ -88,8 +78,6 @@ DefineIndex(char *heapRelationName,
IndexInfo *indexInfo; IndexInfo *indexInfo;
int numberOfAttributes; int numberOfAttributes;
List *cnfPred = NIL; List *cnfPred = NIL;
bool lossy = false;
List *pl;
/* /*
* count attributes in index * count attributes in index
...@@ -129,20 +117,6 @@ DefineIndex(char *heapRelationName, ...@@ -129,20 +117,6 @@ DefineIndex(char *heapRelationName,
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
/*
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
*/
foreach(pl, parameterList)
{
DefElem *param = (DefElem *) lfirst(pl);
if (!strcasecmp(param->defname, "islossy"))
lossy = true;
else
elog(NOTICE, "Unrecognized index attribute \"%s\" ignored",
param->defname);
}
/* /*
* Convert the partial-index predicate from parsetree form to * Convert the partial-index predicate from parsetree form to
* an implicit-AND qual expression, for easier evaluation at runtime. * an implicit-AND qual expression, for easier evaluation at runtime.
...@@ -203,7 +177,7 @@ DefineIndex(char *heapRelationName, ...@@ -203,7 +177,7 @@ DefineIndex(char *heapRelationName,
index_create(heapRelationName, indexRelationName, index_create(heapRelationName, indexRelationName,
indexInfo, accessMethodId, classObjectId, indexInfo, accessMethodId, classObjectId,
lossy, primary, allowSystemTableMods); primary, allowSystemTableMods);
/* /*
* We update the relation's pg_class tuple even if it already has * We update the relation's pg_class tuple even if it already has
...@@ -390,111 +364,109 @@ static Oid ...@@ -390,111 +364,109 @@ static Oid
GetAttrOpClass(IndexElem *attribute, Oid attrType, GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId) char *accessMethodName, Oid accessMethodId)
{ {
Relation relation;
HeapScanDesc scan;
ScanKeyData entry[2];
HeapTuple tuple; HeapTuple tuple;
Oid opClassId, Oid opClassId,
oprId; opInputType;
bool doTypeCheck = true;
if (attribute->class == NULL) if (attribute->class == NULL)
{ {
/* no operator class specified, so find the default */ /* no operator class specified, so find the default */
attribute->class = GetDefaultOpClass(attrType); opClassId = GetDefaultOpClass(attrType, accessMethodId);
if (attribute->class == NULL) if (!OidIsValid(opClassId))
elog(ERROR, "data type %s has no default operator class" elog(ERROR, "data type %s has no default operator class for access method \"%s\""
"\n\tYou must specify an operator class for the index or define a" "\n\tYou must specify an operator class for the index or define a"
"\n\tdefault operator class for the data type", "\n\tdefault operator class for the data type",
format_type_be(attrType)); format_type_be(attrType), accessMethodName);
/* assume we need not check type compatibility */ return opClassId;
doTypeCheck = false;
} }
opClassId = GetSysCacheOid(CLANAME,
PointerGetDatum(attribute->class),
0, 0, 0);
if (!OidIsValid(opClassId))
elog(ERROR, "DefineIndex: opclass \"%s\" not found",
attribute->class);
/* /*
* Assume the opclass is supported by this index access method if we * Find the index operator class and verify that it accepts this
* can find at least one relevant entry in pg_amop. * datatype. Note we will accept binary compatibility.
*/ */
ScanKeyEntryInitialize(&entry[0], 0, tuple = SearchSysCache(CLAAMNAME,
Anum_pg_amop_amopid, ObjectIdGetDatum(accessMethodId),
F_OIDEQ, PointerGetDatum(attribute->class),
ObjectIdGetDatum(accessMethodId)); 0, 0);
ScanKeyEntryInitialize(&entry[1], 0, if (!HeapTupleIsValid(tuple))
Anum_pg_amop_amopclaid, elog(ERROR, "DefineIndex: operator class \"%s\" not supported by access method \"%s\"",
F_OIDEQ,
ObjectIdGetDatum(opClassId));
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
if (!HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
elog(ERROR, "DefineIndex: opclass \"%s\" not supported by access method \"%s\"",
attribute->class, accessMethodName); attribute->class, accessMethodName);
opClassId = tuple->t_data->t_oid;
opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
ReleaseSysCache(tuple);
oprId = ((Form_pg_amop) GETSTRUCT(tuple))->amopopr; if (attrType != opInputType &&
!IS_BINARY_COMPATIBLE(attrType, opInputType))
elog(ERROR, "operator class \"%s\" does not accept data type %s",
attribute->class, format_type_be(attrType));
heap_endscan(scan); return opClassId;
heap_close(relation, AccessShareLock); }
static Oid
GetDefaultOpClass(Oid attrType, Oid accessMethodId)
{
Relation relation;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple tuple;
int nexact = 0;
int ncompatible = 0;
Oid exactOid = InvalidOid;
Oid compatibleOid = InvalidOid;
/* /*
* Make sure the operators associated with this opclass actually * We scan through all the opclasses available for the access method,
* accept the column data type. This prevents possible coredumps * looking for one that is marked default and matches the target type
* caused by user errors like applying text_ops to an int4 column. We * (either exactly or binary-compatibly, but prefer an exact match).
* will accept an opclass as OK if the operator's input datatype is *
* binary-compatible with the actual column datatype. Note we assume * We could find more than one binary-compatible match, in which case we
* that all the operators associated with an opclass accept the same * require the user to specify which one he wants. If we find more than
* datatypes, so checking the first one we happened to find in the * one exact match, then someone put bogus entries in pg_opclass.
* table is sufficient.
* *
* If the opclass was the default for the datatype, assume we can skip * We could use an indexscan here, but since pg_opclass is small
* this check --- that saves a few cycles in the most common case. If * and a scan on opcamid won't be very selective, the indexscan would
* pg_opclass is wrong then we're probably screwed anyway... * probably actually be slower than heapscan.
*/ */
if (doTypeCheck) ScanKeyEntryInitialize(&entry[0], 0x0,
Anum_pg_opclass_opcamid,
F_OIDEQ,
ObjectIdGetDatum(accessMethodId));
relation = heap_openr(OperatorClassRelationName, AccessShareLock);
scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
tuple = SearchSysCache(OPEROID, Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tuple);
ObjectIdGetDatum(oprId),
0, 0, 0); if (opclass->opcdefault)
if (HeapTupleIsValid(tuple))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tuple); if (opclass->opcintype == attrType)
Oid opInputType = (optup->oprkind == 'l') ? {
optup->oprright : optup->oprleft; nexact++;
exactOid = tuple->t_data->t_oid;
if (attrType != opInputType && }
!IS_BINARY_COMPATIBLE(attrType, opInputType)) else if (IS_BINARY_COMPATIBLE(opclass->opcintype, attrType))
elog(ERROR, "operator class \"%s\" does not accept data type %s", {
attribute->class, format_type_be(attrType)); ncompatible++;
ReleaseSysCache(tuple); compatibleOid = tuple->t_data->t_oid;
}
} }
} }
return opClassId; heap_endscan(scan);
} heap_close(relation, AccessShareLock);
static char *
GetDefaultOpClass(Oid atttypid)
{
HeapTuple tuple;
char *result;
tuple = SearchSysCache(CLADEFTYPE,
ObjectIdGetDatum(atttypid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
return NULL;
result = pstrdup(NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname)); if (nexact == 1)
return exactOid;
if (nexact != 0)
elog(ERROR, "pg_opclass contains multiple default opclasses for data tyype %s",
format_type_be(attrType));
if (ncompatible == 1)
return compatibleOid;
ReleaseSysCache(tuple); return InvalidOid;
return result;
} }
/* /*
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.153 2001/08/16 20:38:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.154 2001/08/21 16:36:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1166,7 +1166,6 @@ _copyIndexOptInfo(IndexOptInfo *from) ...@@ -1166,7 +1166,6 @@ _copyIndexOptInfo(IndexOptInfo *from)
newnode->indproc = from->indproc; newnode->indproc = from->indproc;
Node_Copy(from, newnode, indpred); Node_Copy(from, newnode, indpred);
newnode->unique = from->unique; newnode->unique = from->unique;
newnode->lossy = from->lossy;
return newnode; return newnode;
} }
...@@ -2059,7 +2058,6 @@ _copyIndexStmt(IndexStmt *from) ...@@ -2059,7 +2058,6 @@ _copyIndexStmt(IndexStmt *from)
newnode->relname = pstrdup(from->relname); newnode->relname = pstrdup(from->relname);
newnode->accessMethod = pstrdup(from->accessMethod); newnode->accessMethod = pstrdup(from->accessMethod);
Node_Copy(from, newnode, indexParams); Node_Copy(from, newnode, indexParams);
Node_Copy(from, newnode, withClause);
Node_Copy(from, newnode, whereClause); Node_Copy(from, newnode, whereClause);
Node_Copy(from, newnode, rangetable); Node_Copy(from, newnode, rangetable);
newnode->unique = from->unique; newnode->unique = from->unique;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.101 2001/08/16 20:38:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.102 2001/08/21 16:36:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -926,8 +926,6 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b) ...@@ -926,8 +926,6 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
return false; return false;
if (!equal(a->indexParams, b->indexParams)) if (!equal(a->indexParams, b->indexParams))
return false; return false;
if (!equal(a->withClause, b->withClause))
return false;
if (!equal(a->whereClause, b->whereClause)) if (!equal(a->whereClause, b->whereClause))
return false; return false;
if (!equal(a->rangetable, b->rangetable)) if (!equal(a->rangetable, b->rangetable))
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.144 2001/08/16 20:38:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.145 2001/08/21 16:36:02 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -133,16 +133,10 @@ _outIndexStmt(StringInfo str, IndexStmt *node) ...@@ -133,16 +133,10 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
_outToken(str, node->accessMethod); _outToken(str, node->accessMethod);
appendStringInfo(str, " :indexParams "); appendStringInfo(str, " :indexParams ");
_outNode(str, node->indexParams); _outNode(str, node->indexParams);
appendStringInfo(str, " :withClause ");
_outNode(str, node->withClause);
appendStringInfo(str, " :whereClause "); appendStringInfo(str, " :whereClause ");
_outNode(str, node->whereClause); _outNode(str, node->whereClause);
appendStringInfo(str, " :rangetable "); appendStringInfo(str, " :rangetable ");
_outNode(str, node->rangetable); _outNode(str, node->rangetable);
appendStringInfo(str, " :unique %s :primary %s ", appendStringInfo(str, " :unique %s :primary %s ",
booltostr(node->unique), booltostr(node->unique),
booltostr(node->primary)); booltostr(node->primary));
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.77 2001/06/11 00:17:08 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.78 2001/08/21 16:36:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -339,16 +339,16 @@ cost_index(Path *path, Query *root, ...@@ -339,16 +339,16 @@ cost_index(Path *path, Query *root,
* *
* Normally the indexquals will be removed from the list of * Normally the indexquals will be removed from the list of
* restriction clauses that we have to evaluate as qpquals, so we * restriction clauses that we have to evaluate as qpquals, so we
* should subtract their costs from baserestrictcost. For a lossy * should subtract their costs from baserestrictcost. XXX For a lossy
* index, however, we will have to recheck all the quals and so * index, not all the quals will be removed and so we really shouldn't
* mustn't subtract anything. Also, if we are doing a join then some * subtract their costs; but detecting that seems more expensive than
* of the indexquals are join clauses and shouldn't be subtracted. * it's worth. Also, if we are doing a join then some of the indexquals
* Rather than work out exactly how much to subtract, we don't * are join clauses and shouldn't be subtracted. Rather than work out
* subtract anything in that case either. * exactly how much to subtract, we don't subtract anything.
*/ */
cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost; cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost;
if (!index->lossy && !is_injoin) if (!is_injoin)
cpu_per_tuple -= cost_qual_eval(indexQuals); cpu_per_tuple -= cost_qual_eval(indexQuals);
run_cost += cpu_per_tuple * tuples_fetched; run_cost += cpu_per_tuple * tuples_fetched;
......
This diff is collapsed.
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.67 2001/07/15 22:48:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.68 2001/08/21 16:36:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -103,8 +103,7 @@ find_secondary_indexes(Oid relationObjectId) ...@@ -103,8 +103,7 @@ find_secondary_indexes(Oid relationObjectId)
IndexOptInfo *info; IndexOptInfo *info;
int i; int i;
Relation indexRelation; Relation indexRelation;
Oid relam; int16 amorderstrategy;
uint16 amorderstrategy;
indexTuple = SearchSysCache(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid), ObjectIdGetDatum(indexoid),
...@@ -138,7 +137,6 @@ find_secondary_indexes(Oid relationObjectId) ...@@ -138,7 +137,6 @@ find_secondary_indexes(Oid relationObjectId)
else else
info->indpred = NIL; info->indpred = NIL;
info->unique = index->indisunique; info->unique = index->indisunique;
info->lossy = index->indislossy;
for (i = 0; i < INDEX_MAX_KEYS; i++) for (i = 0; i < INDEX_MAX_KEYS; i++)
{ {
...@@ -160,8 +158,7 @@ find_secondary_indexes(Oid relationObjectId) ...@@ -160,8 +158,7 @@ find_secondary_indexes(Oid relationObjectId)
/* Extract info from the relation descriptor for the index */ /* Extract info from the relation descriptor for the index */
indexRelation = index_open(index->indexrelid); indexRelation = index_open(index->indexrelid);
relam = indexRelation->rd_rel->relam; info->relam = indexRelation->rd_rel->relam;
info->relam = relam;
info->pages = indexRelation->rd_rel->relpages; info->pages = indexRelation->rd_rel->relpages;
info->tuples = indexRelation->rd_rel->reltuples; info->tuples = indexRelation->rd_rel->reltuples;
info->amcostestimate = index_cost_estimator(indexRelation); info->amcostestimate = index_cost_estimator(indexRelation);
...@@ -181,14 +178,12 @@ find_secondary_indexes(Oid relationObjectId) ...@@ -181,14 +178,12 @@ find_secondary_indexes(Oid relationObjectId)
amopTuple = amopTuple =
SearchSysCache(AMOPSTRATEGY, SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(relam),
ObjectIdGetDatum(index->indclass[i]), ObjectIdGetDatum(index->indclass[i]),
UInt16GetDatum(amorderstrategy), Int16GetDatum(amorderstrategy),
0); 0, 0);
if (!HeapTupleIsValid(amopTuple)) if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "find_secondary_indexes: no amop %u %u %d", elog(ERROR, "find_secondary_indexes: no amop %u %d",
relam, index->indclass[i], index->indclass[i], (int) amorderstrategy);
(int) amorderstrategy);
amop = (Form_pg_amop) GETSTRUCT(amopTuple); amop = (Form_pg_amop) GETSTRUCT(amopTuple);
info->ordering[i] = amop->amopopr; info->ordering[i] = amop->amopopr;
ReleaseSysCache(amopTuple); ReleaseSysCache(amopTuple);
...@@ -370,7 +365,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno) ...@@ -370,7 +365,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist); IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
/* /*
* Note: ignore functional, partial, or lossy indexes, since they * Note: ignore functional and partial indexes, since they
* don't allow us to conclude that all attr values are distinct. * don't allow us to conclude that all attr values are distinct.
* Also, a multicolumn unique index doesn't allow us to conclude * Also, a multicolumn unique index doesn't allow us to conclude
* that just the specified attr is unique. * that just the specified attr is unique.
...@@ -379,8 +374,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno) ...@@ -379,8 +374,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
index->nkeys == 1 && index->nkeys == 1 &&
index->indexkeys[0] == attno && index->indexkeys[0] == attno &&
index->indproc == InvalidOid && index->indproc == InvalidOid &&
index->indpred == NIL && index->indpred == NIL)
!index->lossy)
return true; return true;
} }
return false; return false;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.195 2001/08/16 20:38:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.196 2001/08/21 16:36:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -995,7 +995,6 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) ...@@ -995,7 +995,6 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
index->relname = stmt->relname; index->relname = stmt->relname;
index->accessMethod = "btree"; index->accessMethod = "btree";
index->indexParams = NIL; index->indexParams = NIL;
index->withClause = NIL;
index->whereClause = NULL; index->whereClause = NULL;
foreach(keys, constraint->keys) foreach(keys, constraint->keys)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.246 2001/08/16 20:38:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.247 2001/08/21 16:36:03 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -2399,13 +2399,12 @@ RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list ...@@ -2399,13 +2399,12 @@ RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
* QUERY: * QUERY:
* create index <indexname> on <relname> * create index <indexname> on <relname>
* [ using <access> ] "(" (<col> with <op>)+ ")" * [ using <access> ] "(" (<col> with <op>)+ ")"
* [ with <parameters> ]
* [ where <predicate> ] * [ where <predicate> ]
* *
*****************************************************************************/ *****************************************************************************/
IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
access_method_clause '(' index_params ')' opt_with where_clause access_method_clause '(' index_params ')' where_clause
{ {
IndexStmt *n = makeNode(IndexStmt); IndexStmt *n = makeNode(IndexStmt);
n->unique = $2; n->unique = $2;
...@@ -2413,8 +2412,7 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name ...@@ -2413,8 +2412,7 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
n->relname = $6; n->relname = $6;
n->accessMethod = $7; n->accessMethod = $7;
n->indexParams = $9; n->indexParams = $9;
n->withClause = $11; n->whereClause = $11;
n->whereClause = $12;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.115 2001/07/16 05:06:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.116 2001/08/21 16:36:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -538,7 +538,6 @@ ProcessUtility(Node *parsetree, ...@@ -538,7 +538,6 @@ ProcessUtility(Node *parsetree,
stmt->idxname, /* index name */ stmt->idxname, /* index name */
stmt->accessMethod, /* am name */ stmt->accessMethod, /* am name */
stmt->indexParams, /* parameters */ stmt->indexParams, /* parameters */
stmt->withClause,
stmt->unique, stmt->unique,
stmt->primary, stmt->primary,
(Expr *) stmt->whereClause, (Expr *) stmt->whereClause,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.62 2001/06/22 19:16:23 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.63 2001/08/21 16:36:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/***************************************************************************** /*****************************************************************************
* USER I/O ROUTINES * * USER I/O ROUTINES *
*****************************************************************************/ *****************************************************************************/
...@@ -32,126 +32,103 @@ ...@@ -32,126 +32,103 @@
/* /*
* regprocin - converts "proname" or "proid" to proid * regprocin - converts "proname" or "proid" to proid
* *
* We need to accept an OID for cases where the name is ambiguous.
*
* proid of '-' signifies unknown, for consistency with regprocout * proid of '-' signifies unknown, for consistency with regprocout
*/ */
Datum Datum
regprocin(PG_FUNCTION_ARGS) regprocin(PG_FUNCTION_ARGS)
{ {
char *pro_name_or_oid = PG_GETARG_CSTRING(0); char *pro_name_or_oid = PG_GETARG_CSTRING(0);
HeapTuple proctup;
HeapTupleData tuple;
RegProcedure result = InvalidOid; RegProcedure result = InvalidOid;
int matches = 0;
ScanKeyData skey[1];
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0') if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
PG_RETURN_OID(InvalidOid); PG_RETURN_OID(InvalidOid);
if (!IsIgnoringSystemIndexes()) if (pro_name_or_oid[0] >= '0' &&
pro_name_or_oid[0] <= '9')
{ {
Oid searchOid;
searchOid = DatumGetObjectId(DirectFunctionCall1(oidin,
CStringGetDatum(pro_name_or_oid)));
result = (RegProcedure) GetSysCacheOid(PROCOID,
ObjectIdGetDatum(searchOid),
0, 0, 0);
if (!RegProcedureIsValid(result))
elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
matches = 1;
}
else if (!IsIgnoringSystemIndexes())
{
Relation hdesc;
Relation idesc;
IndexScanDesc sd;
RetrieveIndexResult indexRes;
HeapTupleData tuple;
Buffer buffer;
ScanKeyEntryInitialize(&skey[0], 0x0,
(AttrNumber) 1,
(RegProcedure) F_NAMEEQ,
CStringGetDatum(pro_name_or_oid));
/* hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
* we need to use the oid because there can be multiple entries idesc = index_openr(ProcedureNameIndex);
* with the same name. We accept int4eq_1323 and 1323. sd = index_beginscan(idesc, false, 1, skey);
*/
if (pro_name_or_oid[0] >= '0' &&
pro_name_or_oid[0] <= '9')
{
result = (RegProcedure)
GetSysCacheOid(PROCOID,
DirectFunctionCall1(oidin,
CStringGetDatum(pro_name_or_oid)),
0, 0, 0);
if (!RegProcedureIsValid(result))
elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
}
else
{
Relation hdesc;
Relation idesc;
IndexScanDesc sd;
ScanKeyData skey[1];
RetrieveIndexResult indexRes;
Buffer buffer;
int matches = 0;
ScanKeyEntryInitialize(&skey[0],
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) F_NAMEEQ,
CStringGetDatum(pro_name_or_oid));
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
idesc = index_openr(ProcedureNameIndex);
sd = index_beginscan(idesc, false, 1, skey); while ((indexRes = index_getnext(sd, ForwardScanDirection)))
while ((indexRes = index_getnext(sd, ForwardScanDirection))) {
tuple.t_datamcxt = NULL;
tuple.t_data = NULL;
tuple.t_self = indexRes->heap_iptr;
heap_fetch(hdesc, SnapshotNow, &tuple, &buffer, sd);
pfree(indexRes);
if (tuple.t_data != NULL)
{ {
tuple.t_datamcxt = NULL; result = (RegProcedure) tuple.t_data->t_oid;
tuple.t_data = NULL; ReleaseBuffer(buffer);
tuple.t_self = indexRes->heap_iptr; if (++matches > 1)
heap_fetch(hdesc, SnapshotNow, break;
&tuple,
&buffer,
sd);
pfree(indexRes);
if (tuple.t_data != NULL)
{
result = (RegProcedure) tuple.t_data->t_oid;
ReleaseBuffer(buffer);
if (++matches > 1)
break;
}
} }
index_endscan(sd);
index_close(idesc);
heap_close(hdesc, AccessShareLock);
if (matches > 1)
elog(ERROR, "There is more than one procedure named %s.\n\tSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
else if (matches == 0)
elog(ERROR, "No procedure with name %s", pro_name_or_oid);
} }
index_endscan(sd);
index_close(idesc);
heap_close(hdesc, AccessShareLock);
} }
else else
{ {
Relation proc; Relation proc;
HeapScanDesc procscan; HeapScanDesc procscan;
ScanKeyData key; HeapTuple proctup;
bool isnull;
proc = heap_openr(ProcedureRelationName, AccessShareLock); ScanKeyEntryInitialize(&skey[0], 0x0,
ScanKeyEntryInitialize(&key, (AttrNumber) Anum_pg_proc_proname,
(bits16) 0,
(AttrNumber) 1,
(RegProcedure) F_NAMEEQ, (RegProcedure) F_NAMEEQ,
CStringGetDatum(pro_name_or_oid)); CStringGetDatum(pro_name_or_oid));
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key); proc = heap_openr(ProcedureRelationName, AccessShareLock);
if (!HeapScanIsValid(procscan)) procscan = heap_beginscan(proc, 0, SnapshotNow, 1, skey);
{
heap_close(proc, AccessShareLock); while (HeapTupleIsValid(proctup = heap_getnext(procscan, 0)))
elog(ERROR, "regprocin: could not begin scan of %s",
ProcedureRelationName);
PG_RETURN_OID(InvalidOid);
}
proctup = heap_getnext(procscan, 0);
if (HeapTupleIsValid(proctup))
{ {
result = (RegProcedure) heap_getattr(proctup, result = proctup->t_data->t_oid;
ObjectIdAttributeNumber, if (++matches > 1)
RelationGetDescr(proc), break;
&isnull);
if (isnull)
elog(ERROR, "regprocin: null procedure %s", pro_name_or_oid);
} }
else
elog(ERROR, "No procedure with name %s", pro_name_or_oid);
heap_endscan(procscan); heap_endscan(procscan);
heap_close(proc, AccessShareLock); heap_close(proc, AccessShareLock);
} }
if (matches > 1)
elog(ERROR, "There is more than one procedure named %s.\n\tSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
else if (matches == 0)
elog(ERROR, "No procedure with name %s", pro_name_or_oid);
PG_RETURN_OID(result); PG_RETURN_OID(result);
} }
...@@ -174,66 +151,22 @@ regprocout(PG_FUNCTION_ARGS) ...@@ -174,66 +151,22 @@ regprocout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
if (!IsBootstrapProcessingMode()) proctup = SearchSysCache(PROCOID,
{ ObjectIdGetDatum(proid),
proctup = SearchSysCache(PROCOID, 0, 0, 0);
ObjectIdGetDatum(proid),
0, 0, 0);
if (HeapTupleIsValid(proctup)) if (HeapTupleIsValid(proctup))
{ {
char *s; char *s;
s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname); s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
StrNCpy(result, s, NAMEDATALEN); StrNCpy(result, s, NAMEDATALEN);
ReleaseSysCache(proctup); ReleaseSysCache(proctup);
}
else
{
result[0] = '-';
result[1] = '\0';
}
} }
else else
{ {
Relation proc; result[0] = '-';
HeapScanDesc procscan; result[1] = '\0';
ScanKeyData key;
proc = heap_openr(ProcedureRelationName, AccessShareLock);
ScanKeyEntryInitialize(&key,
(bits16) 0,
(AttrNumber) ObjectIdAttributeNumber,
(RegProcedure) F_INT4EQ,
ObjectIdGetDatum(proid));
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
if (!HeapScanIsValid(procscan))
{
heap_close(proc, AccessShareLock);
elog(ERROR, "regprocout: could not begin scan of %s",
ProcedureRelationName);
}
proctup = heap_getnext(procscan, 0);
if (HeapTupleIsValid(proctup))
{
char *s;
bool isnull;
s = (char *) heap_getattr(proctup, 1,
RelationGetDescr(proc), &isnull);
if (!isnull)
StrNCpy(result, s, NAMEDATALEN);
else
elog(ERROR, "regprocout: null procedure %u", proid);
}
else
{
result[0] = '-';
result[1] = '\0';
}
heap_endscan(procscan);
heap_close(proc, AccessShareLock);
} }
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.81 2001/06/22 19:16:23 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.82 2001/08/21 16:36:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "access/hash.h" #include "access/hash.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/valid.h" #include "access/valid.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "catalog/catname.h" #include "catalog/catname.h"
...@@ -812,7 +813,7 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) ...@@ -812,7 +813,7 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
sd = heap_beginscan(rel, false, SnapshotNow, 1, &key); sd = heap_beginscan(rel, false, SnapshotNow, 1, &key);
ntp = heap_getnext(sd, 0); ntp = heap_getnext(sd, 0);
if (!HeapTupleIsValid(ntp)) if (!HeapTupleIsValid(ntp))
elog(ERROR, "SearchSelfReferences: %s not found in %s", elog(ERROR, "IndexScanOK: %s not found in %s",
IndexRelidIndex, RelationRelationName); IndexRelidIndex, RelationRelationName);
indexSelfOid = ntp->t_data->t_oid; indexSelfOid = ntp->t_data->t_oid;
heap_endscan(sd); heap_endscan(sd);
...@@ -823,6 +824,16 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) ...@@ -823,6 +824,16 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
if (DatumGetObjectId(cur_skey[0].sk_argument) == indexSelfOid) if (DatumGetObjectId(cur_skey[0].sk_argument) == indexSelfOid)
return false; return false;
} }
else if (cache->id == AMOPSTRATEGY ||
cache->id == AMPROCNUM)
{
/* Looking for an OID or INT2 btree operator or function? */
Oid lookup_oid = DatumGetObjectId(cur_skey[0].sk_argument);
if (lookup_oid == OID_BTREE_OPS_OID ||
lookup_oid == INT2_BTREE_OPS_OID)
return false;
}
else if (cache->id == OPEROID) else if (cache->id == OPEROID)
{ {
/* Looking for an OID comparison function? */ /* Looking for an OID comparison function? */
...@@ -858,7 +869,7 @@ SearchCatCache(CatCache *cache, ...@@ -858,7 +869,7 @@ SearchCatCache(CatCache *cache,
MemoryContext oldcxt; MemoryContext oldcxt;
/* /*
* one-time startup overhead * one-time startup overhead for each cache
*/ */
if (cache->cc_tupdesc == NULL) if (cache->cc_tupdesc == NULL)
CatalogCacheInitializeCache(cache); CatalogCacheInitializeCache(cache);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.56 2001/06/14 01:09:22 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.57 2001/08/21 16:36:05 tgl Exp $
* *
* NOTES * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "postgres.h" #include "postgres.h"
#include "access/tupmacs.h" #include "access/tupmacs.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
...@@ -30,19 +32,48 @@ ...@@ -30,19 +32,48 @@
/* ---------- AMOP CACHES ---------- */ /* ---------- AMOP CACHES ---------- */
/* /*
* op_class * op_in_opclass
* *
* Return t iff operator 'opno' is in operator class 'opclass' for * Return t iff operator 'opno' is in operator class 'opclass'.
* access method 'amopid'.
*/ */
bool bool
op_class(Oid opno, Oid opclass, Oid amopid) op_in_opclass(Oid opno, Oid opclass)
{ {
return SearchSysCacheExists(AMOPOPID, return SearchSysCacheExists(AMOPOPID,
ObjectIdGetDatum(opclass), ObjectIdGetDatum(opclass),
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
ObjectIdGetDatum(amopid), 0, 0);
0); }
/*
* op_requires_recheck
*
* Return t if operator 'opno' requires a recheck when used as a
* member of opclass 'opclass' (ie, this opclass is lossy for this
* operator).
*
* Caller should already have verified that opno is a member of opclass,
* therefore we raise an error if the tuple is not found.
*/
bool
op_requires_recheck(Oid opno, Oid opclass)
{
HeapTuple tp;
Form_pg_amop amop_tup;
bool result;
tp = SearchSysCache(AMOPOPID,
ObjectIdGetDatum(opclass),
ObjectIdGetDatum(opno),
0, 0);
if (!HeapTupleIsValid(tp))
elog(ERROR, "op_requires_recheck: op %u is not a member of opclass %u",
opno, opclass);
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
result = amop_tup->amopreqcheck;
ReleaseSysCache(tp);
return result;
} }
/* ---------- ATTRIBUTE CACHES ---------- */ /* ---------- ATTRIBUTE CACHES ---------- */
...@@ -222,6 +253,33 @@ get_atttypetypmod(Oid relid, AttrNumber attnum, ...@@ -222,6 +253,33 @@ get_atttypetypmod(Oid relid, AttrNumber attnum,
/* watch this space... /* watch this space...
*/ */
/* ---------- OPCLASS CACHE ---------- */
/*
* opclass_is_btree
*
* Returns TRUE iff the specified opclass is associated with the
* btree index access method.
*/
bool
opclass_is_btree(Oid opclass)
{
HeapTuple tp;
Form_pg_opclass cla_tup;
bool result;
tp = SearchSysCache(CLAOID,
ObjectIdGetDatum(opclass),
0, 0, 0);
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for opclass %u", opclass);
cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
result = (cla_tup->opcamid == BTREE_AM_OID);
ReleaseSysCache(tp);
return result;
}
/* ---------- OPERATOR CACHE ---------- */ /* ---------- OPERATOR CACHE ---------- */
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.64 2001/08/10 18:57:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.65 2001/08/21 16:36:05 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_amop.h" #include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_group.h" #include "catalog/pg_group.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
...@@ -113,23 +114,33 @@ static struct cachedesc cacheinfo[] = { ...@@ -113,23 +114,33 @@ static struct cachedesc cacheinfo[] = {
0 0
}}, }},
{AccessMethodOperatorRelationName, /* AMOPOPID */ {AccessMethodOperatorRelationName, /* AMOPOPID */
AccessMethodOpidIndex, AccessMethodOperatorIndex,
0, 0,
3, 2,
{ {
Anum_pg_amop_amopclaid, Anum_pg_amop_amopclaid,
Anum_pg_amop_amopopr, Anum_pg_amop_amopopr,
Anum_pg_amop_amopid, 0,
0 0
}}, }},
{AccessMethodOperatorRelationName, /* AMOPSTRATEGY */ {AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
AccessMethodStrategyIndex, AccessMethodStrategyIndex,
0, 0,
3, 2,
{ {
Anum_pg_amop_amopid,
Anum_pg_amop_amopclaid, Anum_pg_amop_amopclaid,
Anum_pg_amop_amopstrategy, Anum_pg_amop_amopstrategy,
0,
0
}},
{AccessMethodProcedureRelationName, /* AMPROCNUM */
AccessMethodProcedureIndex,
0,
2,
{
Anum_pg_amproc_amopclaid,
Anum_pg_amproc_amprocnum,
0,
0 0
}}, }},
{AttributeRelationName, /* ATTNAME */ {AttributeRelationName, /* ATTNAME */
...@@ -152,22 +163,22 @@ static struct cachedesc cacheinfo[] = { ...@@ -152,22 +163,22 @@ static struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{OperatorClassRelationName, /* CLADEFTYPE */ {OperatorClassRelationName, /* CLAAMNAME */
OpclassDeftypeIndex, OpclassAmNameIndex,
0, 0,
1, 2,
{ {
Anum_pg_opclass_opcdeftype, Anum_pg_opclass_opcamid,
0, Anum_pg_opclass_opcname,
0, 0,
0 0
}}, }},
{OperatorClassRelationName, /* CLANAME */ {OperatorClassRelationName, /* CLAOID */
OpclassNameIndex, OpclassOidIndex,
0, 0,
1, 1,
{ {
Anum_pg_opclass_opcname, ObjectIdAttributeNumber,
0, 0,
0, 0,
0 0
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.17 2001/06/02 19:01:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.18 2001/08/21 16:36:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2055,7 +2055,7 @@ SelectSortFunction(Oid sortOperator, ...@@ -2055,7 +2055,7 @@ SelectSortFunction(Oid sortOperator,
{ {
Relation relation; Relation relation;
HeapScanDesc scan; HeapScanDesc scan;
ScanKeyData skey[3]; ScanKeyData skey[1];
HeapTuple tuple; HeapTuple tuple;
Form_pg_operator optup; Form_pg_operator optup;
Oid opclass = InvalidOid; Oid opclass = InvalidOid;
...@@ -2068,25 +2068,20 @@ SelectSortFunction(Oid sortOperator, ...@@ -2068,25 +2068,20 @@ SelectSortFunction(Oid sortOperator,
* If the operator is registered the same way in multiple opclasses, * If the operator is registered the same way in multiple opclasses,
* assume we can use the associated comparator function from any one. * assume we can use the associated comparator function from any one.
*/ */
relation = heap_openr(AccessMethodOperatorRelationName, ScanKeyEntryInitialize(&skey[0], 0x0,
AccessShareLock);
ScanKeyEntryInitialize(&skey[0], 0,
Anum_pg_amop_amopid,
F_OIDEQ,
ObjectIdGetDatum(BTREE_AM_OID));
ScanKeyEntryInitialize(&skey[1], 0,
Anum_pg_amop_amopopr, Anum_pg_amop_amopopr,
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(sortOperator)); ObjectIdGetDatum(sortOperator));
scan = heap_beginscan(relation, false, SnapshotNow, 2, skey); relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
scan = heap_beginscan(relation, false, SnapshotNow, 1, skey);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple); Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
if (!opclass_is_btree(aform->amopclaid))
continue;
if (aform->amopstrategy == BTLessStrategyNumber) if (aform->amopstrategy == BTLessStrategyNumber)
{ {
opclass = aform->amopclaid; opclass = aform->amopclaid;
...@@ -2107,39 +2102,18 @@ SelectSortFunction(Oid sortOperator, ...@@ -2107,39 +2102,18 @@ SelectSortFunction(Oid sortOperator,
if (OidIsValid(opclass)) if (OidIsValid(opclass))
{ {
/* Found a suitable opclass, get its comparator support function */ /* Found a suitable opclass, get its comparator support function */
relation = heap_openr(AccessMethodProcedureRelationName, tuple = SearchSysCache(AMPROCNUM,
AccessShareLock); ObjectIdGetDatum(opclass),
Int16GetDatum(BTORDER_PROC),
ScanKeyEntryInitialize(&skey[0], 0, 0, 0);
Anum_pg_amproc_amid, if (HeapTupleIsValid(tuple))
F_OIDEQ,
ObjectIdGetDatum(BTREE_AM_OID));
ScanKeyEntryInitialize(&skey[1], 0,
Anum_pg_amproc_amopclaid,
F_OIDEQ,
ObjectIdGetDatum(opclass));
ScanKeyEntryInitialize(&skey[2], 0,
Anum_pg_amproc_amprocnum,
F_INT2EQ,
Int16GetDatum(BTORDER_PROC));
scan = heap_beginscan(relation, false, SnapshotNow, 3, skey);
*sortFunction = InvalidOid;
if (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Form_pg_amproc aform = (Form_pg_amproc) GETSTRUCT(tuple); Form_pg_amproc aform = (Form_pg_amproc) GETSTRUCT(tuple);
*sortFunction = aform->amproc; *sortFunction = aform->amproc;
} ReleaseSysCache(tuple);
Assert(RegProcedureIsValid(*sortFunction));
heap_endscan(scan);
heap_close(relation, AccessShareLock);
if (RegProcedureIsValid(*sortFunction))
return; return;
}
} }
/* /*
...@@ -2158,7 +2132,7 @@ SelectSortFunction(Oid sortOperator, ...@@ -2158,7 +2132,7 @@ SelectSortFunction(Oid sortOperator,
*kind = SORTFUNC_REVLT; *kind = SORTFUNC_REVLT;
else else
*kind = SORTFUNC_LT; *kind = SORTFUNC_LT;
*sortFunction = optup->oprcode; *sortFunction = optup->oprcode;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
Assert(RegProcedureIsValid(*sortFunction)); Assert(RegProcedureIsValid(*sortFunction));
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.38 2001/08/10 18:57:39 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.39 2001/08/21 16:36:05 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "describe.h" #include "describe.h"
...@@ -653,7 +653,7 @@ describeTableDetails(const char *name, bool desc) ...@@ -653,7 +653,7 @@ describeTableDetails(const char *name, bool desc)
/* Footer information about an index */ /* Footer information about an index */
PGresult *result; PGresult *result;
sprintf(buf, "SELECT i.indisunique, i.indisprimary, i.indislossy, a.amname,\n" sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname,\n"
" pg_get_expr(i.indpred, i.indrelid) as indpred\n" " pg_get_expr(i.indpred, i.indrelid) as indpred\n"
"FROM pg_index i, pg_class c, pg_am a\n" "FROM pg_index i, pg_class c, pg_am a\n"
"WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid", "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid",
...@@ -666,9 +666,8 @@ describeTableDetails(const char *name, bool desc) ...@@ -666,9 +666,8 @@ describeTableDetails(const char *name, bool desc)
{ {
char *indisunique = PQgetvalue(result, 0, 0); char *indisunique = PQgetvalue(result, 0, 0);
char *indisprimary = PQgetvalue(result, 0, 1); char *indisprimary = PQgetvalue(result, 0, 1);
char *indislossy = PQgetvalue(result, 0, 2); char *indamname = PQgetvalue(result, 0, 2);
char *indamname = PQgetvalue(result, 0, 3); char *indpred = PQgetvalue(result, 0, 3);
char *indpred = PQgetvalue(result, 0, 4);
footers = xmalloc(3 * sizeof(*footers)); footers = xmalloc(3 * sizeof(*footers));
/* XXX This construction is poorly internationalized. */ /* XXX This construction is poorly internationalized. */
...@@ -680,10 +679,6 @@ describeTableDetails(const char *name, bool desc) ...@@ -680,10 +679,6 @@ describeTableDetails(const char *name, bool desc)
snprintf(footers[0] + strlen(footers[0]), snprintf(footers[0] + strlen(footers[0]),
NAMEDATALEN + 128 - strlen(footers[0]), NAMEDATALEN + 128 - strlen(footers[0]),
_(" (primary key)")); _(" (primary key)"));
if (strcmp(indislossy, "t") == 0)
snprintf(footers[0] + strlen(footers[0]),
NAMEDATALEN + 128 - strlen(footers[0]),
_(" (lossy)"));
if (strlen(indpred) > 0) if (strlen(indpred) > 0)
{ {
footers[1] = xmalloc(64 + strlen(indpred)); footers[1] = xmalloc(64 + strlen(indpred));
...@@ -694,6 +689,8 @@ describeTableDetails(const char *name, bool desc) ...@@ -694,6 +689,8 @@ describeTableDetails(const char *name, bool desc)
else else
footers[1] = NULL; footers[1] = NULL;
} }
PQclear(result);
} }
else if (view_def) else if (view_def)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: gist.h,v 1.30 2001/08/10 14:34:28 momjian Exp $ * $Id: gist.h,v 1.31 2001/08/21 16:36:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -73,8 +73,8 @@ typedef struct GISTSTATE ...@@ -73,8 +73,8 @@ typedef struct GISTSTATE
FmgrInfo picksplitFn[INDEX_MAX_KEYS]; FmgrInfo picksplitFn[INDEX_MAX_KEYS];
FmgrInfo equalFn[INDEX_MAX_KEYS]; FmgrInfo equalFn[INDEX_MAX_KEYS];
bool attbyval[INDEX_MAX_KEYS]; bool attbyval[INDEX_MAX_KEYS];
bool haskeytype; bool haskeytype[INDEX_MAX_KEYS];
bool keytypbyval; bool keytypbyval[INDEX_MAX_KEYS];
} GISTSTATE; } GISTSTATE;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.90 2001/08/16 20:38:54 tgl Exp $ * $Id: catversion.h,v 1.91 2001/08/21 16:36:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200108151 #define CATALOG_VERSION_NO 200108211
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: index.h,v 1.38 2001/08/10 18:57:39 tgl Exp $ * $Id: index.h,v 1.39 2001/08/21 16:36:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -39,7 +39,6 @@ extern Oid index_create(char *heapRelationName, ...@@ -39,7 +39,6 @@ extern Oid index_create(char *heapRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid accessMethodObjectId, Oid accessMethodObjectId,
Oid *classObjectId, Oid *classObjectId,
bool islossy,
bool primary, bool primary,
bool allow_system_table_mods); bool allow_system_table_mods);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: indexing.h,v 1.52 2001/08/10 18:57:39 tgl Exp $ * $Id: indexing.h,v 1.53 2001/08/21 16:36:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define Num_pg_inherits_indices 1 #define Num_pg_inherits_indices 1
#define Num_pg_language_indices 2 #define Num_pg_language_indices 2
#define Num_pg_largeobject_indices 1 #define Num_pg_largeobject_indices 1
#define Num_pg_opclass_indices 3 #define Num_pg_opclass_indices 2
#define Num_pg_operator_indices 2 #define Num_pg_operator_indices 2
#define Num_pg_proc_indices 2 #define Num_pg_proc_indices 2
#define Num_pg_relcheck_indices 1 #define Num_pg_relcheck_indices 1
...@@ -47,9 +47,9 @@ ...@@ -47,9 +47,9 @@
/* /*
* Names of indices on system catalogs * Names of indices on system catalogs
*/ */
#define AccessMethodOpidIndex "pg_amop_opid_index" #define AccessMethodOperatorIndex "pg_amop_opc_opr_index"
#define AccessMethodStrategyIndex "pg_amop_strategy_index" #define AccessMethodStrategyIndex "pg_amop_opc_strategy_index"
#define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index" #define AccessMethodProcedureIndex "pg_amproc_opc_procnum_index"
#define AggregateNameTypeIndex "pg_aggregate_name_type_index" #define AggregateNameTypeIndex "pg_aggregate_name_type_index"
#define AggregateOidIndex "pg_aggregate_oid_index" #define AggregateOidIndex "pg_aggregate_oid_index"
#define AmNameIndex "pg_am_name_index" #define AmNameIndex "pg_am_name_index"
...@@ -70,8 +70,7 @@ ...@@ -70,8 +70,7 @@
#define LanguageNameIndex "pg_language_name_index" #define LanguageNameIndex "pg_language_name_index"
#define LanguageOidIndex "pg_language_oid_index" #define LanguageOidIndex "pg_language_oid_index"
#define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index" #define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index"
#define OpclassDeftypeIndex "pg_opclass_deftype_index" #define OpclassAmNameIndex "pg_opclass_am_name_index"
#define OpclassNameIndex "pg_opclass_name_index"
#define OpclassOidIndex "pg_opclass_oid_index" #define OpclassOidIndex "pg_opclass_oid_index"
#define OperatorNameIndex "pg_operator_oprname_l_r_k_index" #define OperatorNameIndex "pg_operator_oprname_l_r_k_index"
#define OperatorOidIndex "pg_operator_oid_index" #define OperatorOidIndex "pg_operator_oid_index"
...@@ -155,9 +154,9 @@ DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(ag ...@@ -155,9 +154,9 @@ DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(ag
DECLARE_UNIQUE_INDEX(pg_aggregate_oid_index on pg_aggregate using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_aggregate_oid_index on pg_aggregate using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops)); DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops)); DECLARE_UNIQUE_INDEX(pg_amop_opc_opr_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops));
DECLARE_UNIQUE_INDEX(pg_amop_strategy_index on pg_amop using btree(amopid oid_ops, amopclaid oid_ops, amopstrategy int2_ops)); DECLARE_UNIQUE_INDEX(pg_amop_opc_strategy_index on pg_amop using btree(amopclaid oid_ops, amopstrategy int2_ops));
DECLARE_UNIQUE_INDEX(pg_amproc_am_opcl_procnum_index on pg_amproc using btree(amid oid_ops, amopclaid oid_ops, amprocnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_amproc_opc_procnum_index on pg_amproc using btree(amopclaid oid_ops, amprocnum int2_ops));
DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
...@@ -175,9 +174,7 @@ DECLARE_UNIQUE_INDEX(pg_inherits_relid_seqno_index on pg_inherits using btree(in ...@@ -175,9 +174,7 @@ DECLARE_UNIQUE_INDEX(pg_inherits_relid_seqno_index on pg_inherits using btree(in
DECLARE_UNIQUE_INDEX(pg_language_name_index on pg_language using btree(lanname name_ops)); DECLARE_UNIQUE_INDEX(pg_language_name_index on pg_language using btree(lanname name_ops));
DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops)); DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops));
/* This column needs to allow multiple zero entries, but is in the cache */ DECLARE_UNIQUE_INDEX(pg_opclass_am_name_index on pg_opclass using btree(opcamid oid_ops, opcname name_ops));
DECLARE_INDEX(pg_opclass_deftype_index on pg_opclass using btree(opcdeftype oid_ops));
DECLARE_UNIQUE_INDEX(pg_opclass_name_index on pg_opclass using btree(opcname name_ops));
DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops));
......
This diff is collapsed.
...@@ -2,15 +2,19 @@ ...@@ -2,15 +2,19 @@
* *
* pg_amproc.h * pg_amproc.h
* definition of the system "amproc" relation (pg_amproc) * definition of the system "amproc" relation (pg_amproc)
* along with the relation's initial contents. The amproc * along with the relation's initial contents.
* catalog is used to store procedures used by index access *
* methods that aren't associated with operators. * The amproc table identifies support procedures associated with index
* opclasses. These procedures can't be listed in pg_amop since they are
* not associated with indexable operators for the opclass.
*
* Note: the primary key for this table is <amopclaid, amprocnum>.
* *
* *
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_amproc.h,v 1.29 2001/08/13 18:45:36 tgl Exp $ * $Id: pg_amproc.h,v 1.30 2001/08/21 16:36:05 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -35,10 +39,9 @@ ...@@ -35,10 +39,9 @@
*/ */
CATALOG(pg_amproc) BKI_WITHOUT_OIDS CATALOG(pg_amproc) BKI_WITHOUT_OIDS
{ {
Oid amid; /* the access method this proc is for */ Oid amopclaid; /* the index opclass this entry is for */
Oid amopclaid; /* the opclass this proc is for */
Oid amproc; /* OID of the proc */
int2 amprocnum; /* support procedure index */ int2 amprocnum; /* support procedure index */
regproc amproc; /* OID of the proc */
} FormData_pg_amproc; } FormData_pg_amproc;
/* ---------------- /* ----------------
...@@ -52,11 +55,10 @@ typedef FormData_pg_amproc *Form_pg_amproc; ...@@ -52,11 +55,10 @@ typedef FormData_pg_amproc *Form_pg_amproc;
* compiler constants for pg_amproc * compiler constants for pg_amproc
* ---------------- * ----------------
*/ */
#define Natts_pg_amproc 4 #define Natts_pg_amproc 3
#define Anum_pg_amproc_amid 1 #define Anum_pg_amproc_amopclaid 1
#define Anum_pg_amproc_amopclaid 2 #define Anum_pg_amproc_amprocnum 2
#define Anum_pg_amproc_amproc 3 #define Anum_pg_amproc_amproc 3
#define Anum_pg_amproc_amprocnum 4
/* ---------------- /* ----------------
* initial contents of pg_amproc * initial contents of pg_amproc
...@@ -64,66 +66,66 @@ typedef FormData_pg_amproc *Form_pg_amproc; ...@@ -64,66 +66,66 @@ typedef FormData_pg_amproc *Form_pg_amproc;
*/ */
/* rtree */ /* rtree */
DATA(insert (402 422 193 1)); DATA(insert ( 422 1 193 ));
DATA(insert (402 422 194 2)); DATA(insert ( 422 2 194 ));
DATA(insert (402 422 195 3)); DATA(insert ( 422 3 196 ));
DATA(insert (402 433 193 1)); DATA(insert ( 425 1 193 ));
DATA(insert (402 433 194 2)); DATA(insert ( 425 2 194 ));
DATA(insert (402 433 196 3)); DATA(insert ( 425 3 195 ));
DATA(insert (402 434 197 1)); DATA(insert ( 1993 1 197 ));
DATA(insert (402 434 198 2)); DATA(insert ( 1993 2 198 ));
DATA(insert (402 434 199 3)); DATA(insert ( 1993 3 199 ));
/* btree */ /* btree */
DATA(insert (403 421 350 1)); DATA(insert ( 421 1 357 ));
DATA(insert (403 423 355 1)); DATA(insert ( 423 1 1596 ));
DATA(insert (403 426 351 1)); DATA(insert ( 424 1 1693 ));
DATA(insert (403 427 356 1)); DATA(insert ( 426 1 1078 ));
DATA(insert (403 428 354 1)); DATA(insert ( 428 1 1954 ));
DATA(insert (403 429 358 1)); DATA(insert ( 429 1 358 ));
DATA(insert (403 431 360 1)); DATA(insert ( 432 1 926 ));
DATA(insert (403 432 357 1)); DATA(insert ( 434 1 1092 ));
DATA(insert (403 435 404 1)); DATA(insert ( 1970 1 354 ));
DATA(insert (403 754 842 1)); DATA(insert ( 1972 1 355 ));
DATA(insert (403 1076 1078 1)); DATA(insert ( 1974 1 926 ));
DATA(insert (403 1077 1079 1)); DATA(insert ( 1976 1 350 ));
DATA(insert (403 1114 1092 1)); DATA(insert ( 1978 1 351 ));
DATA(insert (403 1115 1107 1)); DATA(insert ( 1980 1 842 ));
DATA(insert (403 1181 359 1)); DATA(insert ( 1982 1 1315 ));
DATA(insert (403 1312 1314 1)); DATA(insert ( 1984 1 836 ));
DATA(insert (403 1313 1315 1)); DATA(insert ( 1986 1 359 ));
DATA(insert (403 810 836 1)); DATA(insert ( 1988 1 1769 ));
DATA(insert (403 935 926 1)); DATA(insert ( 1989 1 356 ));
DATA(insert (403 652 926 1)); DATA(insert ( 1991 1 404 ));
DATA(insert (403 1768 1769 1)); DATA(insert ( 1994 1 360 ));
DATA(insert (403 1690 1693 1)); DATA(insert ( 1996 1 1107 ));
DATA(insert (403 1399 1358 1)); DATA(insert ( 1998 1 1314 ));
DATA(insert (403 424 1596 1)); DATA(insert ( 2000 1 1358 ));
DATA(insert (403 425 1672 1)); DATA(insert ( 2002 1 1672 ));
DATA(insert (403 1961 1954 1)); DATA(insert ( 2003 1 1079 ));
/* hash */ /* hash */
DATA(insert (405 421 449 1)); DATA(insert ( 427 1 1080 ));
DATA(insert (405 423 452 1)); DATA(insert ( 431 1 454 ));
DATA(insert (405 426 450 1)); DATA(insert ( 433 1 456 ));
DATA(insert (405 427 453 1)); DATA(insert ( 435 1 450 ));
DATA(insert (405 428 451 1)); DATA(insert ( 1971 1 451 ));
DATA(insert (405 429 454 1)); DATA(insert ( 1973 1 452 ));
DATA(insert (405 431 456 1)); DATA(insert ( 1975 1 456 ));
DATA(insert (405 435 457 1)); DATA(insert ( 1977 1 449 ));
DATA(insert (405 652 456 1)); DATA(insert ( 1979 1 450 ));
DATA(insert (405 754 949 1)); DATA(insert ( 1981 1 949 ));
DATA(insert (405 810 399 1)); DATA(insert ( 1983 1 1697 ));
DATA(insert (405 935 456 1)); DATA(insert ( 1985 1 399 ));
DATA(insert (405 1076 1080 1)); DATA(insert ( 1987 1 455 ));
DATA(insert (405 1077 456 1)); DATA(insert ( 1990 1 453 ));
DATA(insert (405 1114 450 1)); DATA(insert ( 1992 1 457 ));
DATA(insert (405 1115 452 1)); DATA(insert ( 1995 1 456 ));
DATA(insert (405 1181 455 1)); DATA(insert ( 1997 1 452 ));
DATA(insert (405 1312 452 1)); DATA(insert ( 1999 1 452 ));
DATA(insert (405 1313 1697 1)); DATA(insert ( 2001 1 1696 ));
DATA(insert (405 1399 1696 1)); DATA(insert ( 2004 1 456 ));
#endif /* PG_AMPROC_H */ #endif /* PG_AMPROC_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment