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
-- register the default opclass for indexing
INSERT INTO pg_opclass (opcname, opcdeftype)
SELECT 'gist_cube_ops', oid
FROM pg_type
WHERE typname = 'cube';
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_cube_ops',
(SELECT oid FROM pg_type WHERE typname = 'cube'),
true,
0);
-- get the comparators for boxes and store them in a tmp table
SELECT o.oid AS opoid, o.oprname
INTO TABLE gist_cube_ops_tmp
INTO TEMP TABLE gist_cube_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'cube';
......@@ -231,59 +234,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid
-- using the tmp table, generate the amop entries
-- cube_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 1
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 1, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '<<';
-- cube_over_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 2
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 2, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&<';
-- cube_overlap
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 3
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 3, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&&';
-- cube_over_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 4
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 4, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&>';
-- cube_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 5
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 5, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '>>';
-- cube_same
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 6
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 6, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '=';
-- cube_contains
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 7
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 7, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '@';
-- cube_contained
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 8
FROM pg_am am, pg_opclass opcl, gist_cube_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 8, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '~';
DROP TABLE gist_cube_ops_tmp;
......@@ -292,46 +311,60 @@ DROP TABLE gist_cube_ops_tmp;
-- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 1
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 1, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_consistent';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 2
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 2, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_union';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 3
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 3, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_compress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 4
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 4, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_decompress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 5
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 5, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_penalty';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 6
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 6, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_picksplit';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 7
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_cube_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 7, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_same';
END TRANSACTION;
......@@ -48,10 +48,8 @@ Join pg_am.amrestrpos => pg_proc.oid
Join pg_am.ambuild => pg_proc.oid
Join pg_am.ambulkdelete => 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.amopopr => pg_operator.oid
Join pg_amproc.amid => pg_am.oid
Join pg_amproc.amopclaid => pg_opclass.oid
Join pg_amproc.amproc => pg_proc.oid
Join pg_attribute.attrelid => pg_class.oid
......@@ -63,7 +61,8 @@ Join pg_class.reltoastidxid => pg_class.oid
Join pg_description.classoid => pg_class.oid
Join pg_index.indexrelid => 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.oprright => pg_type.oid
Join pg_operator.oprresult => pg_type.oid
......
......@@ -68,15 +68,17 @@ main(int argc, char **argv)
if (strcmp(typname, "oid") == 0)
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \
SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.\"%s\" = t2.oid ", relname, relname2, attname);
WHERE t1.\"%s\" = t2.oid ",
relname, relname2, attname);
else
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \
FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.\"%s\") = t2.oid ", relname, relname2, attname);
SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.\"%s\") = t2.oid ",
relname, relname2, attname);
doquery(query);
doquery("FETCH ALL IN c_matches");
......
This is an implementation of RD-tree data structure using GiST interface
of PostgreSQL. It has built-in lossy compression - must be declared
in index creation - with (islossy). Current implementation provides index
support for one-dimensional array of int4's - gist__int_ops, suitable for
small and medium size of arrays (used on default), and gist__intbig_ops for
indexing large arrays (we use superimposed signature with length of 4096
bits to represent sets).
of PostgreSQL. It has built-in lossy compression.
Current implementation provides index support for one-dimensional array of
int4's - gist__int_ops, suitable for small and medium size of arrays (used on
default), and gist__intbig_ops for indexing large arrays (we use superimposed
signature with length of 4096 bits to represent sets).
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
......@@ -35,7 +35,7 @@ EXAMPLE USAGE:
-- create indices
CREATE unique index message_key on message ( 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 message.mid from message where message.sections && '{1,2}';
......
This diff is collapsed.
......@@ -49,7 +49,7 @@ print <<EOT;
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_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;
select count(*) from message;
......
......@@ -17,7 +17,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}';
12
(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}';
count
-------
......@@ -31,7 +31,7 @@ SELECT count(*) from test__int WHERE a @ '{23,50}';
(1 row)
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}';
count
-------
......
......@@ -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}';
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}';
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}';
......
......@@ -36,7 +36,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
(1 row)
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;
count
-------
......
This diff is collapsed.
......@@ -32,7 +32,7 @@ select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon;
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;
......@@ -236,15 +236,18 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque
-- register the default opclass for indexing
INSERT INTO pg_opclass (opcname, opcdeftype)
SELECT 'gist_seg_ops', oid
FROM pg_type
WHERE typname = 'seg';
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'),
'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
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
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'seg';
......@@ -255,59 +258,75 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid
-- using the tmp table, generate the amop entries
-- seg_left
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 1
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 1, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '<<';
-- seg_overleft
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 2
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 2, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&<';
-- seg_overlap
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 3
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 3, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&&';
-- seg_overright
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 4
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 4, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '&>';
-- seg_right
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 5
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 5, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '>>';
-- seg_same
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 6
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 6, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '=';
-- seg_contains
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 7
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 7, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '@';
-- seg_contained
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 8
FROM pg_am am, pg_opclass opcl, seg_ops_tmp c
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 8, false, c.opoid
FROM pg_opclass opcl, seg_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and c.oprname = '~';
DROP TABLE seg_ops_tmp;
......@@ -316,46 +335,60 @@ DROP TABLE seg_ops_tmp;
-- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 1
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 1, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_consistent';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 2
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 2, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_union';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 3
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 3, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_compress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 4
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 4, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_decompress';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 5
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 5, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_penalty';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 6
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 6, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_picksplit';
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT am.oid, opcl.oid, pro.oid, 7
FROM pg_am am, pg_opclass opcl, pg_proc pro
WHERE amname = 'gist' and opcname = 'gist_seg_ops'
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 7, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_seg_ops'
and proname = 'gseg_same';
END TRANSACTION;
<!--
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">
......@@ -1050,13 +1050,6 @@
<entry>unused</entry>
</row>
<row>
<entry>indislossy</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>???</entry>
</row>
<row>
<entry>indisunique</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">
<title id="indexes-title">Indexes</title>
......@@ -401,15 +401,14 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
<para>
The following query shows all defined operator classes:
<programlisting>
SELECT am.amname AS acc_name,
SELECT am.amname AS acc_method,
opc.opcname AS ops_name,
opr.oprname AS ops_comp
FROM pg_am am, pg_amop amop,
pg_opclass opc, pg_operator opr
WHERE amop.amopid = am.oid AND
FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr
WHERE opc.opcamid = am.oid AND
amop.amopclaid = opc.oid AND
amop.amopopr = opr.oid
ORDER BY acc_name, ops_name, ops_comp;
ORDER BY acc_method, ops_name, ops_comp
</programlisting>
</para>
</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
-->
......@@ -374,9 +374,8 @@ ERROR: Cannot create index: 'index_name' already exists.
SELECT am.amname AS acc_method,
opc.opcname AS ops_name,
opr.oprname AS ops_comp
FROM pg_am am, pg_amop amop,
pg_opclass opc, pg_operator opr
WHERE amop.amopid = am.oid AND
FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr
WHERE opc.opcamid = am.oid AND
amop.amopclaid = opc.oid AND
amop.amopopr = opr.oid
ORDER BY acc_method, ops_name, ops_comp
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 @@
#include "access/heapam.h"
#include "catalog/index.h"
#include "catalog/pg_index.h"
#include "catalog/pg_opclass.h"
#include "executor/executor.h"
#include "miscadmin.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "access/xlogutils.h"
......@@ -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))
{
IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
sum_grow=0;
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);
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);
......@@ -1548,20 +1549,32 @@ initGISTstate(GISTSTATE *giststate, Relation index)
RegProcedure consistent_proc,
union_proc,
compress_proc,
decompress_proc;
RegProcedure penalty_proc,
decompress_proc,
penalty_proc,
picksplit_proc,
equal_proc;
HeapTuple htup;
HeapTuple itup;
HeapTuple ctup;
Form_pg_index itupform;
Oid indexrelid;
Form_pg_opclass opclassform;
Oid inputtype;
Oid keytype;
int i;
if (index->rd_att->natts >= INDEX_MAX_KEYS)
elog(ERROR, "initGISTstate: numberOfAttributes %d > %d",
index->rd_att->natts, INDEX_MAX_KEYS);
if (index->rd_att->natts > INDEX_MAX_KEYS)
elog(ERROR, "initGISTstate: numberOfAttributes %d > %d",
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 );
union_proc = index_getprocid(index, i+1, GIST_UNION_PROC );
compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC );
......@@ -1577,37 +1590,35 @@ initGISTstate(GISTSTATE *giststate, Relation index)
fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) );
fmgr_info(equal_proc, &((giststate->equalFn)[i]) );
giststate->attbyval[i] =
index->rd_att->attrs[i]->attbyval;
/* Check opclass entry to see if there is a keytype */
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 */
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;
ReleaseSysCache(itup);
}
#ifdef GIST_PAGEADDITEM
......@@ -1670,7 +1681,7 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
GISTENTRY *dep;
gistentryinit(*e, k, r, pg, o, b, l);
if (giststate->haskeytype)
if (giststate->haskeytype[nkey])
{
if ( b && ! isNull ) {
dep = (GISTENTRY *)
......@@ -1698,7 +1709,7 @@ gistcentryinit(GISTSTATE *giststate, int nkey,
GISTENTRY *cep;
gistentryinit(*e, k, r, pg, o, b, l);
if (giststate->haskeytype)
if (giststate->haskeytype[nkey])
{
if ( ! isNull ) {
cep = (GISTENTRY *)
......@@ -1792,7 +1803,7 @@ gistpenalty( GISTSTATE *giststate, int attno,
FunctionCall3(&giststate->penaltyFn[attno],
PointerGetDatum(key1),
PointerGetDatum(key2),
PointerGetDatum(&penalty));
PointerGetDatum(penalty));
}
#ifdef GISTDEBUG
......
......@@ -9,7 +9,7 @@
*
*
* 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,
#endif
/* ----------------
* OperatorRelationFillScanKeyEntry
* FillScanKeyEntry
*
* Initialize a ScanKey entry given already-opened pg_operator relation.
* Initialize a ScanKey entry for the given operator OID.
* ----------------
*/
static void
OperatorRelationFillScanKeyEntry(Relation operatorRelation,
Oid operatorObjectId,
ScanKey entry)
FillScanKeyEntry(Oid operatorObjectId, ScanKey entry)
{
HeapTuple tuple;
HeapScanDesc scan = NULL;
bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
if (cachesearch)
{
tuple = SearchSysCache(OPEROID,
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);
}
tuple = SearchSysCache(OPEROID,
ObjectIdGetDatum(operatorObjectId),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
if (!cachesearch)
heap_endscan(scan);
elog(ERROR, "OperatorRelationFillScanKeyEntry: unknown operator %u",
elog(ERROR, "FillScanKeyEntry: unknown operator %u",
operatorObjectId);
}
MemSet(entry, 0, sizeof(*entry));
entry->sk_flags = 0;
entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode;
if (cachesearch)
ReleaseSysCache(tuple);
else
heap_endscan(scan);
ReleaseSysCache(tuple);
if (!RegProcedureIsValid(entry->sk_procedure))
elog(ERROR,
"OperatorRelationFillScanKeyEntry: no procedure for operator %u",
elog(ERROR, "FillScanKeyEntry: no procedure for operator %u",
operatorObjectId);
/*
......@@ -548,160 +519,99 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
StrategyNumber maxSupportNumber,
AttrNumber maxAttributeNumber)
{
Relation relation = NULL;
HeapScanDesc scan = NULL;
ScanKeyData entry[2];
Relation operatorRelation;
HeapTuple tuple;
Form_pg_index iform;
StrategyMap map;
AttrNumber attNumber;
int attIndex;
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);
scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
tuple = heap_getnext(scan, 0);
}
maxStrategyNumber = AMStrategies(maxStrategyNumber);
tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexObjectId),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "IndexSupportInitialize: no pg_index entry for index %u",
indexObjectId);
iform = (Form_pg_index) GETSTRUCT(tuple);
*isUnique = iform->indisunique;
maxStrategyNumber = AMStrategies(maxStrategyNumber);
/*
* XXX note that the following assumes the INDEX tuple is well formed
* and that the *key and *class are 0 terminated.
*/
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
if (!OidIsValid(iform->indkey[attIndex]))
{
if (attIndex == InvalidAttrNumber)
elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
break;
}
if (iform->indkey[attIndex] == InvalidAttrNumber ||
!OidIsValid(iform->indclass[attIndex]))
elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
operatorClassObjectId[attIndex] = iform->indclass[attIndex];
}
if (cachesearch)
ReleaseSysCache(tuple);
else
{
heap_endscan(scan);
heap_close(relation, AccessShareLock);
}
ReleaseSysCache(tuple);
/* if support routines exist for this access method, load them */
if (maxSupportNumber > 0)
{
ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
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++)
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
Oid opclass = operatorClassObjectId[attIndex];
RegProcedure *loc;
StrategyNumber support;
loc = &indexSupport[((attNumber - 1) * maxSupportNumber)];
loc = &indexSupport[attIndex * maxSupportNumber];
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;
aform = (Form_pg_amproc) GETSTRUCT(tuple);
support = aform->amprocnum;
Assert(support > 0 && support <= maxSupportNumber);
loc[support - 1] = aform->amproc;
tuple = SearchSysCache(AMPROCNUM,
ObjectIdGetDatum(opclass),
Int16GetDatum(support+1),
0, 0);
if (HeapTupleIsValid(tuple))
{
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 */
ScanKeyEntryInitialize(&entry[0], 0,
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--)
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
Oid opclass = operatorClassObjectId[attIndex];
StrategyMap map;
StrategyNumber strategy;
entry[1].sk_argument =
ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
map = IndexStrategyGetStrategyMap(indexStrategy,
maxStrategyNumber,
attNumber);
attIndex + 1);
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)))
{
Form_pg_amop aform;
aform = (Form_pg_amop) GETSTRUCT(tuple);
strategy = aform->amopstrategy;
Assert(strategy > 0 && strategy <= maxStrategyNumber);
OperatorRelationFillScanKeyEntry(operatorRelation,
aform->amopopr,
StrategyMapGetScanKeyEntry(map, strategy));
amopform = (Form_pg_amop) GETSTRUCT(tuple);
FillScanKeyEntry(amopform->amopopr, mapentry);
ReleaseSysCache(tuple);
}
else
ScanKeyEntrySetIllegal(mapentry);
}
heap_endscan(scan);
}
heap_close(operatorRelation, AccessShareLock);
heap_close(relation, AccessShareLock);
}
/* ----------------
......
......@@ -9,7 +9,7 @@
*
*
* 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:
DefineIndex(LexIDStr($5),
LexIDStr($3),
LexIDStr($7),
$9, NIL, 0, 0, 0, NIL);
$9, false, false, NULL, NIL);
do_end();
}
;
......@@ -259,7 +259,7 @@ Boot_DeclareUniqueIndexStmt:
DefineIndex(LexIDStr($6),
LexIDStr($4),
LexIDStr($8),
$10, NIL, 1, 0, 0, NIL);
$10, true, false, NULL, NIL);
do_end();
}
;
......
......@@ -8,7 +8,7 @@
*
*
* 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
......@@ -71,9 +71,9 @@ static void InitializeAttributeOids(Relation indexRelation,
int numatts, Oid indexoid);
static void AppendAttributeTuples(Relation indexRelation, int numatts);
static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
IndexInfo *indexInfo,
Oid *classOids,
bool islossy, bool primary);
IndexInfo *indexInfo,
Oid *classOids,
bool primary);
static Oid IndexGetRelation(Oid indexId);
static bool activate_index(Oid indexId, bool activate, bool inplace);
......@@ -495,7 +495,6 @@ UpdateIndexRelation(Oid indexoid,
Oid heapoid,
IndexInfo *indexInfo,
Oid *classOids,
bool islossy,
bool primary)
{
Form_pg_index indexForm;
......@@ -535,8 +534,6 @@ UpdateIndexRelation(Oid indexoid,
indexForm->indrelid = heapoid;
indexForm->indproc = indexInfo->ii_FuncOid;
indexForm->indisclustered = false; /* not used */
indexForm->indislossy = islossy;
indexForm->indhaskeytype = true; /* used by GIST */
indexForm->indisunique = indexInfo->ii_Unique;
indexForm->indisprimary = primary;
memcpy((char *) &indexForm->indpred, (char *) predText, predLen);
......@@ -671,7 +668,6 @@ index_create(char *heapRelationName,
IndexInfo *indexInfo,
Oid accessMethodObjectId,
Oid *classObjectId,
bool islossy,
bool primary,
bool allow_system_table_mods)
{
......@@ -779,7 +775,7 @@ index_create(char *heapRelationName,
* ----------------
*/
UpdateIndexRelation(indexoid, heapoid, indexInfo,
classObjectId, islossy, primary);
classObjectId, primary);
/*
* initialize the index strategy
......
......@@ -9,7 +9,7 @@
*
*
* 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] =
char *Name_pg_am_indices[Num_pg_am_indices] =
{AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] =
{AccessMethodOpidIndex, AccessMethodStrategyIndex};
{AccessMethodOperatorIndex, AccessMethodStrategyIndex};
char *Name_pg_amproc_indices[Num_pg_amproc_indices] =
{AccessProcedureIndex};
{AccessMethodProcedureIndex};
char *Name_pg_attr_indices[Num_pg_attr_indices] =
{AttributeRelidNameIndex, AttributeRelidNumIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
......@@ -58,7 +58,7 @@ char *Name_pg_language_indices[Num_pg_language_indices] =
char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
{LargeObjectLOidPNIndex};
char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
{OpclassDeftypeIndex, OpclassNameIndex, OpclassOidIndex};
{OpclassAmNameIndex, OpclassOidIndex};
char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] =
......
......@@ -15,7 +15,7 @@
*
*
* 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)
indexInfo,
Old_pg_index_relation_Form->relam,
Old_pg_index_Form->indclass,
Old_pg_index_Form->indislossy,
Old_pg_index_Form->indisprimary,
allowSystemTableMods);
......
......@@ -8,7 +8,7 @@
*
*
* 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
* The PerformAddAttribute() code, like most of the relation
......@@ -1902,12 +1902,12 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
indexInfo->ii_FuncOid = InvalidOid;
indexInfo->ii_Unique = true;
classObjectId[0] = OID_OPS_OID;
classObjectId[1] = INT4_OPS_OID;
classObjectId[0] = OID_BTREE_OPS_OID;
classObjectId[1] = INT4_BTREE_OPS_OID;
toast_idxid = index_create(toast_relname, toast_idxname, indexInfo,
BTREE_AM_OID, classObjectId,
false, true, true);
true, true);
/*
* Update toast rel's pg_class entry to show that it has an index.
......
......@@ -8,26 +8,19 @@
*
*
* 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 "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/heap.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_operator.h"
#include "catalog/pg_proc.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
......@@ -36,7 +29,6 @@
#include "parser/parsetree.h"
#include "parser/parse_coerce.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
......@@ -57,7 +49,7 @@ static void NormIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
char *accessMethodName, Oid accessMethodId);
static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId);
static char *GetDefaultOpClass(Oid atttypid);
static Oid GetDefaultOpClass(Oid attrType, Oid accessMethodId);
/*
* DefineIndex
......@@ -65,16 +57,14 @@ static char *GetDefaultOpClass(Oid atttypid);
*
* 'attributeList' is a list of IndexElem specifying either a functional
* 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.
* 'rangetable' is needed to interpret the predicate
* 'rangetable' is needed to interpret the predicate.
*/
void
DefineIndex(char *heapRelationName,
char *indexRelationName,
char *accessMethodName,
List *attributeList,
List *parameterList,
bool unique,
bool primary,
Expr *predicate,
......@@ -88,8 +78,6 @@ DefineIndex(char *heapRelationName,
IndexInfo *indexInfo;
int numberOfAttributes;
List *cnfPred = NIL;
bool lossy = false;
List *pl;
/*
* count attributes in index
......@@ -129,20 +117,6 @@ DefineIndex(char *heapRelationName,
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
* an implicit-AND qual expression, for easier evaluation at runtime.
......@@ -203,7 +177,7 @@ DefineIndex(char *heapRelationName,
index_create(heapRelationName, indexRelationName,
indexInfo, accessMethodId, classObjectId,
lossy, primary, allowSystemTableMods);
primary, allowSystemTableMods);
/*
* We update the relation's pg_class tuple even if it already has
......@@ -390,111 +364,109 @@ static Oid
GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId)
{
Relation relation;
HeapScanDesc scan;
ScanKeyData entry[2];
HeapTuple tuple;
Oid opClassId,
oprId;
bool doTypeCheck = true;
opInputType;
if (attribute->class == NULL)
{
/* no operator class specified, so find the default */
attribute->class = GetDefaultOpClass(attrType);
if (attribute->class == NULL)
elog(ERROR, "data type %s has no default operator class"
opClassId = GetDefaultOpClass(attrType, accessMethodId);
if (!OidIsValid(opClassId))
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\tdefault operator class for the data type",
format_type_be(attrType));
/* assume we need not check type compatibility */
doTypeCheck = false;
format_type_be(attrType), accessMethodName);
return opClassId;
}
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
* can find at least one relevant entry in pg_amop.
* Find the index operator class and verify that it accepts this
* datatype. Note we will accept binary compatibility.
*/
ScanKeyEntryInitialize(&entry[0], 0,
Anum_pg_amop_amopid,
F_OIDEQ,
ObjectIdGetDatum(accessMethodId));
ScanKeyEntryInitialize(&entry[1], 0,
Anum_pg_amop_amopclaid,
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\"",
tuple = SearchSysCache(CLAAMNAME,
ObjectIdGetDatum(accessMethodId),
PointerGetDatum(attribute->class),
0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: operator class \"%s\" not supported by access method \"%s\"",
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);
heap_close(relation, AccessShareLock);
return opClassId;
}
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
* accept the column data type. This prevents possible coredumps
* caused by user errors like applying text_ops to an int4 column. We
* will accept an opclass as OK if the operator's input datatype is
* binary-compatible with the actual column datatype. Note we assume
* that all the operators associated with an opclass accept the same
* datatypes, so checking the first one we happened to find in the
* table is sufficient.
* We scan through all the opclasses available for the access method,
* looking for one that is marked default and matches the target type
* (either exactly or binary-compatibly, but prefer an exact match).
*
* We could find more than one binary-compatible match, in which case we
* require the user to specify which one he wants. If we find more than
* one exact match, then someone put bogus entries in pg_opclass.
*
* If the opclass was the default for the datatype, assume we can skip
* this check --- that saves a few cycles in the most common case. If
* pg_opclass is wrong then we're probably screwed anyway...
* We could use an indexscan here, but since pg_opclass is small
* and a scan on opcamid won't be very selective, the indexscan would
* 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,
ObjectIdGetDatum(oprId),
0, 0, 0);
if (HeapTupleIsValid(tuple))
Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tuple);
if (opclass->opcdefault)
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tuple);
Oid opInputType = (optup->oprkind == 'l') ?
optup->oprright : optup->oprleft;
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));
ReleaseSysCache(tuple);
if (opclass->opcintype == attrType)
{
nexact++;
exactOid = tuple->t_data->t_oid;
}
else if (IS_BINARY_COMPATIBLE(opclass->opcintype, attrType))
{
ncompatible++;
compatibleOid = tuple->t_data->t_oid;
}
}
}
return opClassId;
}
static char *
GetDefaultOpClass(Oid atttypid)
{
HeapTuple tuple;
char *result;
tuple = SearchSysCache(CLADEFTYPE,
ObjectIdGetDatum(atttypid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
return NULL;
heap_endscan(scan);
heap_close(relation, AccessShareLock);
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 result;
return InvalidOid;
}
/*
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
newnode->indproc = from->indproc;
Node_Copy(from, newnode, indpred);
newnode->unique = from->unique;
newnode->lossy = from->lossy;
return newnode;
}
......@@ -2059,7 +2058,6 @@ _copyIndexStmt(IndexStmt *from)
newnode->relname = pstrdup(from->relname);
newnode->accessMethod = pstrdup(from->accessMethod);
Node_Copy(from, newnode, indexParams);
Node_Copy(from, newnode, withClause);
Node_Copy(from, newnode, whereClause);
Node_Copy(from, newnode, rangetable);
newnode->unique = from->unique;
......
......@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
return false;
if (!equal(a->indexParams, b->indexParams))
return false;
if (!equal(a->withClause, b->withClause))
return false;
if (!equal(a->whereClause, b->whereClause))
return false;
if (!equal(a->rangetable, b->rangetable))
......
......@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -133,16 +133,10 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
_outToken(str, node->accessMethod);
appendStringInfo(str, " :indexParams ");
_outNode(str, node->indexParams);
appendStringInfo(str, " :withClause ");
_outNode(str, node->withClause);
appendStringInfo(str, " :whereClause ");
_outNode(str, node->whereClause);
appendStringInfo(str, " :rangetable ");
_outNode(str, node->rangetable);
appendStringInfo(str, " :unique %s :primary %s ",
booltostr(node->unique),
booltostr(node->primary));
......
......@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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,
*
* Normally the indexquals will be removed from the list of
* restriction clauses that we have to evaluate as qpquals, so we
* should subtract their costs from baserestrictcost. For a lossy
* index, however, we will have to recheck all the quals and so
* mustn't subtract anything. Also, if we are doing a join then some
* of the indexquals are join clauses and shouldn't be subtracted.
* Rather than work out exactly how much to subtract, we don't
* subtract anything in that case either.
* should subtract their costs from baserestrictcost. XXX For a lossy
* index, not all the quals will be removed and so we really shouldn't
* subtract their costs; but detecting that seems more expensive than
* it's worth. Also, if we are doing a join then some of the indexquals
* are join clauses and shouldn't be subtracted. Rather than work out
* exactly how much to subtract, we don't subtract anything.
*/
cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost;
if (!index->lossy && !is_injoin)
if (!is_injoin)
cpu_per_tuple -= cost_qual_eval(indexQuals);
run_cost += cpu_per_tuple * tuples_fetched;
......
This diff is collapsed.
This diff is collapsed.
......@@ -9,7 +9,7 @@
*
*
* 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)
IndexOptInfo *info;
int i;
Relation indexRelation;
Oid relam;
uint16 amorderstrategy;
int16 amorderstrategy;
indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid),
......@@ -138,7 +137,6 @@ find_secondary_indexes(Oid relationObjectId)
else
info->indpred = NIL;
info->unique = index->indisunique;
info->lossy = index->indislossy;
for (i = 0; i < INDEX_MAX_KEYS; i++)
{
......@@ -160,8 +158,7 @@ find_secondary_indexes(Oid relationObjectId)
/* Extract info from the relation descriptor for the index */
indexRelation = index_open(index->indexrelid);
relam = indexRelation->rd_rel->relam;
info->relam = relam;
info->relam = indexRelation->rd_rel->relam;
info->pages = indexRelation->rd_rel->relpages;
info->tuples = indexRelation->rd_rel->reltuples;
info->amcostestimate = index_cost_estimator(indexRelation);
......@@ -181,14 +178,12 @@ find_secondary_indexes(Oid relationObjectId)
amopTuple =
SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(relam),
ObjectIdGetDatum(index->indclass[i]),
UInt16GetDatum(amorderstrategy),
0);
Int16GetDatum(amorderstrategy),
0, 0);
if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
relam, index->indclass[i],
(int) amorderstrategy);
elog(ERROR, "find_secondary_indexes: no amop %u %d",
index->indclass[i], (int) amorderstrategy);
amop = (Form_pg_amop) GETSTRUCT(amopTuple);
info->ordering[i] = amop->amopopr;
ReleaseSysCache(amopTuple);
......@@ -370,7 +365,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
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.
* Also, a multicolumn unique index doesn't allow us to conclude
* that just the specified attr is unique.
......@@ -379,8 +374,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
index->nkeys == 1 &&
index->indexkeys[0] == attno &&
index->indproc == InvalidOid &&
index->indpred == NIL &&
!index->lossy)
index->indpred == NIL)
return true;
}
return false;
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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)
index->relname = stmt->relname;
index->accessMethod = "btree";
index->indexParams = NIL;
index->withClause = NIL;
index->whereClause = NULL;
foreach(keys, constraint->keys)
......
......@@ -11,7 +11,7 @@
*
*
* 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
* AUTHOR DATE MAJOR EVENT
......@@ -2399,13 +2399,12 @@ RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
* QUERY:
* create index <indexname> on <relname>
* [ using <access> ] "(" (<col> with <op>)+ ")"
* [ with <parameters> ]
* [ where <predicate> ]
*
*****************************************************************************/
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);
n->unique = $2;
......@@ -2413,8 +2412,7 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
n->relname = $6;
n->accessMethod = $7;
n->indexParams = $9;
n->withClause = $11;
n->whereClause = $12;
n->whereClause = $11;
$$ = (Node *)n;
}
;
......
......@@ -10,7 +10,7 @@
*
*
* 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,
stmt->idxname, /* index name */
stmt->accessMethod, /* am name */
stmt->indexParams, /* parameters */
stmt->withClause,
stmt->unique,
stmt->primary,
(Expr *) stmt->whereClause,
......
......@@ -8,7 +8,7 @@
*
*
* 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 @@
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
/*****************************************************************************
* USER I/O ROUTINES *
*****************************************************************************/
......@@ -32,126 +32,103 @@
/*
* 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
*/
Datum
regprocin(PG_FUNCTION_ARGS)
{
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
HeapTuple proctup;
HeapTupleData tuple;
RegProcedure result = InvalidOid;
int matches = 0;
ScanKeyData skey[1];
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
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));
/*
* we need to use the oid because there can be multiple entries
* with the same name. We accept int4eq_1323 and 1323.
*/
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);
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
idesc = index_openr(ProcedureNameIndex);
sd = index_beginscan(idesc, false, 1, skey);
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;
tuple.t_data = NULL;
tuple.t_self = indexRes->heap_iptr;
heap_fetch(hdesc, SnapshotNow,
&tuple,
&buffer,
sd);
pfree(indexRes);
if (tuple.t_data != NULL)
{
result = (RegProcedure) tuple.t_data->t_oid;
ReleaseBuffer(buffer);
if (++matches > 1)
break;
}
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
{
Relation proc;
HeapScanDesc procscan;
ScanKeyData key;
bool isnull;
HeapTuple proctup;
proc = heap_openr(ProcedureRelationName, AccessShareLock);
ScanKeyEntryInitialize(&key,
(bits16) 0,
(AttrNumber) 1,
ScanKeyEntryInitialize(&skey[0], 0x0,
(AttrNumber) Anum_pg_proc_proname,
(RegProcedure) F_NAMEEQ,
CStringGetDatum(pro_name_or_oid));
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
if (!HeapScanIsValid(procscan))
{
heap_close(proc, AccessShareLock);
elog(ERROR, "regprocin: could not begin scan of %s",
ProcedureRelationName);
PG_RETURN_OID(InvalidOid);
}
proctup = heap_getnext(procscan, 0);
if (HeapTupleIsValid(proctup))
proc = heap_openr(ProcedureRelationName, AccessShareLock);
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, skey);
while (HeapTupleIsValid(proctup = heap_getnext(procscan, 0)))
{
result = (RegProcedure) heap_getattr(proctup,
ObjectIdAttributeNumber,
RelationGetDescr(proc),
&isnull);
if (isnull)
elog(ERROR, "regprocin: null procedure %s", pro_name_or_oid);
result = proctup->t_data->t_oid;
if (++matches > 1)
break;
}
else
elog(ERROR, "No procedure with name %s", pro_name_or_oid);
heap_endscan(procscan);
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);
}
......@@ -174,66 +151,22 @@ regprocout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result);
}
if (!IsBootstrapProcessingMode())
{
proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(proid),
0, 0, 0);
proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(proid),
0, 0, 0);
if (HeapTupleIsValid(proctup))
{
char *s;
if (HeapTupleIsValid(proctup))
{
char *s;
s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
StrNCpy(result, s, NAMEDATALEN);
ReleaseSysCache(proctup);
}
else
{
result[0] = '-';
result[1] = '\0';
}
s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
StrNCpy(result, s, NAMEDATALEN);
ReleaseSysCache(proctup);
}
else
{
Relation proc;
HeapScanDesc procscan;
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);
result[0] = '-';
result[1] = '\0';
}
PG_RETURN_CSTRING(result);
......
......@@ -8,7 +8,7 @@
*
*
* 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 @@
#include "access/hash.h"
#include "access/heapam.h"
#include "access/valid.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "catalog/catname.h"
......@@ -812,7 +813,7 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
sd = heap_beginscan(rel, false, SnapshotNow, 1, &key);
ntp = heap_getnext(sd, 0);
if (!HeapTupleIsValid(ntp))
elog(ERROR, "SearchSelfReferences: %s not found in %s",
elog(ERROR, "IndexScanOK: %s not found in %s",
IndexRelidIndex, RelationRelationName);
indexSelfOid = ntp->t_data->t_oid;
heap_endscan(sd);
......@@ -823,6 +824,16 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
if (DatumGetObjectId(cur_skey[0].sk_argument) == indexSelfOid)
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)
{
/* Looking for an OID comparison function? */
......@@ -858,7 +869,7 @@ SearchCatCache(CatCache *cache,
MemoryContext oldcxt;
/*
* one-time startup overhead
* one-time startup overhead for each cache
*/
if (cache->cc_tupdesc == NULL)
CatalogCacheInitializeCache(cache);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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
* Eventually, the index information should go through here, too.
......@@ -16,6 +16,8 @@
#include "postgres.h"
#include "access/tupmacs.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h"
......@@ -30,19 +32,48 @@
/* ---------- AMOP CACHES ---------- */
/*
* op_class
* op_in_opclass
*
* Return t iff operator 'opno' is in operator class 'opclass' for
* access method 'amopid'.
* Return t iff operator 'opno' is in operator class 'opclass'.
*/
bool
op_class(Oid opno, Oid opclass, Oid amopid)
op_in_opclass(Oid opno, Oid opclass)
{
return SearchSysCacheExists(AMOPOPID,
ObjectIdGetDatum(opclass),
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 ---------- */
......@@ -222,6 +253,33 @@ get_atttypetypmod(Oid relid, AttrNumber attnum,
/* 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 ---------- */
/*
......
......@@ -8,7 +8,7 @@
*
*
* 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
* These routines allow the parser/planner/executor to perform
......@@ -27,6 +27,7 @@
#include "catalog/indexing.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_group.h"
#include "catalog/pg_index.h"
#include "catalog/pg_inherits.h"
......@@ -113,23 +114,33 @@ static struct cachedesc cacheinfo[] = {
0
}},
{AccessMethodOperatorRelationName, /* AMOPOPID */
AccessMethodOpidIndex,
AccessMethodOperatorIndex,
0,
3,
2,
{
Anum_pg_amop_amopclaid,
Anum_pg_amop_amopopr,
Anum_pg_amop_amopid,
0,
0
}},
{AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
AccessMethodStrategyIndex,
0,
3,
2,
{
Anum_pg_amop_amopid,
Anum_pg_amop_amopclaid,
Anum_pg_amop_amopstrategy,
0,
0
}},
{AccessMethodProcedureRelationName, /* AMPROCNUM */
AccessMethodProcedureIndex,
0,
2,
{
Anum_pg_amproc_amopclaid,
Anum_pg_amproc_amprocnum,
0,
0
}},
{AttributeRelationName, /* ATTNAME */
......@@ -152,22 +163,22 @@ static struct cachedesc cacheinfo[] = {
0,
0
}},
{OperatorClassRelationName, /* CLADEFTYPE */
OpclassDeftypeIndex,
{OperatorClassRelationName, /* CLAAMNAME */
OpclassAmNameIndex,
0,
1,
2,
{
Anum_pg_opclass_opcdeftype,
0,
Anum_pg_opclass_opcamid,
Anum_pg_opclass_opcname,
0,
0
}},
{OperatorClassRelationName, /* CLANAME */
OpclassNameIndex,
{OperatorClassRelationName, /* CLAOID */
OpclassOidIndex,
0,
1,
{
Anum_pg_opclass_opcname,
ObjectIdAttributeNumber,
0,
0,
0
......
......@@ -78,7 +78,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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,
{
Relation relation;
HeapScanDesc scan;
ScanKeyData skey[3];
ScanKeyData skey[1];
HeapTuple tuple;
Form_pg_operator optup;
Oid opclass = InvalidOid;
......@@ -2068,25 +2068,20 @@ SelectSortFunction(Oid sortOperator,
* If the operator is registered the same way in multiple opclasses,
* assume we can use the associated comparator function from any one.
*/
relation = heap_openr(AccessMethodOperatorRelationName,
AccessShareLock);
ScanKeyEntryInitialize(&skey[0], 0,
Anum_pg_amop_amopid,
F_OIDEQ,
ObjectIdGetDatum(BTREE_AM_OID));
ScanKeyEntryInitialize(&skey[1], 0,
ScanKeyEntryInitialize(&skey[0], 0x0,
Anum_pg_amop_amopopr,
F_OIDEQ,
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)))
{
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
if (!opclass_is_btree(aform->amopclaid))
continue;
if (aform->amopstrategy == BTLessStrategyNumber)
{
opclass = aform->amopclaid;
......@@ -2107,39 +2102,18 @@ SelectSortFunction(Oid sortOperator,
if (OidIsValid(opclass))
{
/* Found a suitable opclass, get its comparator support function */
relation = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock);
ScanKeyEntryInitialize(&skey[0], 0,
Anum_pg_amproc_amid,
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)))
tuple = SearchSysCache(AMPROCNUM,
ObjectIdGetDatum(opclass),
Int16GetDatum(BTORDER_PROC),
0, 0);
if (HeapTupleIsValid(tuple))
{
Form_pg_amproc aform = (Form_pg_amproc) GETSTRUCT(tuple);
*sortFunction = aform->amproc;
}
heap_endscan(scan);
heap_close(relation, AccessShareLock);
if (RegProcedureIsValid(*sortFunction))
ReleaseSysCache(tuple);
Assert(RegProcedureIsValid(*sortFunction));
return;
}
}
/*
......@@ -2158,7 +2132,7 @@ SelectSortFunction(Oid sortOperator,
*kind = SORTFUNC_REVLT;
else
*kind = SORTFUNC_LT;
*sortFunction = optup->oprcode;
*sortFunction = optup->oprcode;
ReleaseSysCache(tuple);
Assert(RegProcedureIsValid(*sortFunction));
......
......@@ -3,7 +3,7 @@
*
* 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 "describe.h"
......@@ -653,7 +653,7 @@ describeTableDetails(const char *name, bool desc)
/* Footer information about an index */
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"
"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",
......@@ -666,9 +666,8 @@ describeTableDetails(const char *name, bool desc)
{
char *indisunique = PQgetvalue(result, 0, 0);
char *indisprimary = PQgetvalue(result, 0, 1);
char *indislossy = PQgetvalue(result, 0, 2);
char *indamname = PQgetvalue(result, 0, 3);
char *indpred = PQgetvalue(result, 0, 4);
char *indamname = PQgetvalue(result, 0, 2);
char *indpred = PQgetvalue(result, 0, 3);
footers = xmalloc(3 * sizeof(*footers));
/* XXX This construction is poorly internationalized. */
......@@ -680,10 +679,6 @@ describeTableDetails(const char *name, bool desc)
snprintf(footers[0] + strlen(footers[0]),
NAMEDATALEN + 128 - strlen(footers[0]),
_(" (primary key)"));
if (strcmp(indislossy, "t") == 0)
snprintf(footers[0] + strlen(footers[0]),
NAMEDATALEN + 128 - strlen(footers[0]),
_(" (lossy)"));
if (strlen(indpred) > 0)
{
footers[1] = xmalloc(64 + strlen(indpred));
......@@ -694,6 +689,8 @@ describeTableDetails(const char *name, bool desc)
else
footers[1] = NULL;
}
PQclear(result);
}
else if (view_def)
{
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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
FmgrInfo picksplitFn[INDEX_MAX_KEYS];
FmgrInfo equalFn[INDEX_MAX_KEYS];
bool attbyval[INDEX_MAX_KEYS];
bool haskeytype;
bool keytypbyval;
bool haskeytype[INDEX_MAX_KEYS];
bool keytypbyval[INDEX_MAX_KEYS];
} GISTSTATE;
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200108151
#define CATALOG_VERSION_NO 200108211
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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,
IndexInfo *indexInfo,
Oid accessMethodObjectId,
Oid *classObjectId,
bool islossy,
bool primary,
bool allow_system_table_mods);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 @@
#define Num_pg_inherits_indices 1
#define Num_pg_language_indices 2
#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_proc_indices 2
#define Num_pg_relcheck_indices 1
......@@ -47,9 +47,9 @@
/*
* Names of indices on system catalogs
*/
#define AccessMethodOpidIndex "pg_amop_opid_index"
#define AccessMethodStrategyIndex "pg_amop_strategy_index"
#define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index"
#define AccessMethodOperatorIndex "pg_amop_opc_opr_index"
#define AccessMethodStrategyIndex "pg_amop_opc_strategy_index"
#define AccessMethodProcedureIndex "pg_amproc_opc_procnum_index"
#define AggregateNameTypeIndex "pg_aggregate_name_type_index"
#define AggregateOidIndex "pg_aggregate_oid_index"
#define AmNameIndex "pg_am_name_index"
......@@ -70,8 +70,7 @@
#define LanguageNameIndex "pg_language_name_index"
#define LanguageOidIndex "pg_language_oid_index"
#define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index"
#define OpclassDeftypeIndex "pg_opclass_deftype_index"
#define OpclassNameIndex "pg_opclass_name_index"
#define OpclassAmNameIndex "pg_opclass_am_name_index"
#define OpclassOidIndex "pg_opclass_oid_index"
#define OperatorNameIndex "pg_operator_oprname_l_r_k_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
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_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_strategy_index on pg_amop using btree(amopid oid_ops, 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_amop_opc_opr_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_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_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_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));
......@@ -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_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));
/* This column needs to allow multiple zero entries, but is in the cache */
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_am_name_index on pg_opclass using btree(opcamid oid_ops, opcname name_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_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 @@
*
* pg_amproc.h
* definition of the system "amproc" relation (pg_amproc)
* along with the relation's initial contents. The amproc
* catalog is used to store procedures used by index access
* methods that aren't associated with operators.
* along with the relation's initial contents.
*
* 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) 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
* the genbki.sh script reads this file and generates .bki
......@@ -35,10 +39,9 @@
*/
CATALOG(pg_amproc) BKI_WITHOUT_OIDS
{
Oid amid; /* the access method this proc is for */
Oid amopclaid; /* the opclass this proc is for */
Oid amproc; /* OID of the proc */
Oid amopclaid; /* the index opclass this entry is for */
int2 amprocnum; /* support procedure index */
regproc amproc; /* OID of the proc */
} FormData_pg_amproc;
/* ----------------
......@@ -52,11 +55,10 @@ typedef FormData_pg_amproc *Form_pg_amproc;
* compiler constants for pg_amproc
* ----------------
*/
#define Natts_pg_amproc 4
#define Anum_pg_amproc_amid 1
#define Anum_pg_amproc_amopclaid 2
#define Natts_pg_amproc 3
#define Anum_pg_amproc_amopclaid 1
#define Anum_pg_amproc_amprocnum 2
#define Anum_pg_amproc_amproc 3
#define Anum_pg_amproc_amprocnum 4
/* ----------------
* initial contents of pg_amproc
......@@ -64,66 +66,66 @@ typedef FormData_pg_amproc *Form_pg_amproc;
*/
/* rtree */
DATA(insert (402 422 193 1));
DATA(insert (402 422 194 2));
DATA(insert (402 422 195 3));
DATA(insert (402 433 193 1));
DATA(insert (402 433 194 2));
DATA(insert (402 433 196 3));
DATA(insert (402 434 197 1));
DATA(insert (402 434 198 2));
DATA(insert (402 434 199 3));
DATA(insert ( 422 1 193 ));
DATA(insert ( 422 2 194 ));
DATA(insert ( 422 3 196 ));
DATA(insert ( 425 1 193 ));
DATA(insert ( 425 2 194 ));
DATA(insert ( 425 3 195 ));
DATA(insert ( 1993 1 197 ));
DATA(insert ( 1993 2 198 ));
DATA(insert ( 1993 3 199 ));
/* btree */
DATA(insert (403 421 350 1));
DATA(insert (403 423 355 1));
DATA(insert (403 426 351 1));
DATA(insert (403 427 356 1));
DATA(insert (403 428 354 1));
DATA(insert (403 429 358 1));
DATA(insert (403 431 360 1));
DATA(insert (403 432 357 1));
DATA(insert (403 435 404 1));
DATA(insert (403 754 842 1));
DATA(insert (403 1076 1078 1));
DATA(insert (403 1077 1079 1));
DATA(insert (403 1114 1092 1));
DATA(insert (403 1115 1107 1));
DATA(insert (403 1181 359 1));
DATA(insert (403 1312 1314 1));
DATA(insert (403 1313 1315 1));
DATA(insert (403 810 836 1));
DATA(insert (403 935 926 1));
DATA(insert (403 652 926 1));
DATA(insert (403 1768 1769 1));
DATA(insert (403 1690 1693 1));
DATA(insert (403 1399 1358 1));
DATA(insert (403 424 1596 1));
DATA(insert (403 425 1672 1));
DATA(insert (403 1961 1954 1));
DATA(insert ( 421 1 357 ));
DATA(insert ( 423 1 1596 ));
DATA(insert ( 424 1 1693 ));
DATA(insert ( 426 1 1078 ));
DATA(insert ( 428 1 1954 ));
DATA(insert ( 429 1 358 ));
DATA(insert ( 432 1 926 ));
DATA(insert ( 434 1 1092 ));
DATA(insert ( 1970 1 354 ));
DATA(insert ( 1972 1 355 ));
DATA(insert ( 1974 1 926 ));
DATA(insert ( 1976 1 350 ));
DATA(insert ( 1978 1 351 ));
DATA(insert ( 1980 1 842 ));
DATA(insert ( 1982 1 1315 ));
DATA(insert ( 1984 1 836 ));
DATA(insert ( 1986 1 359 ));
DATA(insert ( 1988 1 1769 ));
DATA(insert ( 1989 1 356 ));
DATA(insert ( 1991 1 404 ));
DATA(insert ( 1994 1 360 ));
DATA(insert ( 1996 1 1107 ));
DATA(insert ( 1998 1 1314 ));
DATA(insert ( 2000 1 1358 ));
DATA(insert ( 2002 1 1672 ));
DATA(insert ( 2003 1 1079 ));
/* hash */
DATA(insert (405 421 449 1));
DATA(insert (405 423 452 1));
DATA(insert (405 426 450 1));
DATA(insert (405 427 453 1));
DATA(insert (405 428 451 1));
DATA(insert (405 429 454 1));
DATA(insert (405 431 456 1));
DATA(insert (405 435 457 1));
DATA(insert (405 652 456 1));
DATA(insert (405 754 949 1));
DATA(insert (405 810 399 1));
DATA(insert (405 935 456 1));
DATA(insert (405 1076 1080 1));
DATA(insert (405 1077 456 1));
DATA(insert (405 1114 450 1));
DATA(insert (405 1115 452 1));
DATA(insert (405 1181 455 1));
DATA(insert (405 1312 452 1));
DATA(insert (405 1313 1697 1));
DATA(insert (405 1399 1696 1));
DATA(insert ( 427 1 1080 ));
DATA(insert ( 431 1 454 ));
DATA(insert ( 433 1 456 ));
DATA(insert ( 435 1 450 ));
DATA(insert ( 1971 1 451 ));
DATA(insert ( 1973 1 452 ));
DATA(insert ( 1975 1 456 ));
DATA(insert ( 1977 1 449 ));
DATA(insert ( 1979 1 450 ));
DATA(insert ( 1981 1 949 ));
DATA(insert ( 1983 1 1697 ));
DATA(insert ( 1985 1 399 ));
DATA(insert ( 1987 1 455 ));
DATA(insert ( 1990 1 453 ));
DATA(insert ( 1992 1 457 ));
DATA(insert ( 1995 1 456 ));
DATA(insert ( 1997 1 452 ));
DATA(insert ( 1999 1 452 ));
DATA(insert ( 2001 1 1696 ));
DATA(insert ( 2004 1 456 ));
#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