1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-12 02:37:31 +03:00

Cross-data-type comparisons are now indexable by btrees, pursuant to my

pghackers proposal of 8-Nov.  All the existing cross-type comparison
operators (int2/int4/int8 and float4/float8) have appropriate support.
The original proposal of storing the right-hand-side datatype as part of
the primary key for pg_amop and pg_amproc got modified a bit in the event;
it is easier to store zero as the 'default' case and only store a nonzero
when the operator is actually cross-type.  Along the way, remove the
long-since-defunct bigbox_ops operator class.
This commit is contained in:
Tom Lane
2003-11-12 21:15:59 +00:00
parent 49f98fa833
commit fa5c8a055a
76 changed files with 2237 additions and 1492 deletions

View File

@@ -47,7 +47,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
-- in the regression test (we check them using the sequoia 2000
-- benchmark).
--
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
-- there's no easy way to check that this command actually is using
-- the index, unfortunately. (EXPLAIN would work, but its output
-- changes too often for me to want to put an EXPLAIN in the test...)

View File

@@ -129,6 +129,14 @@ WHERE amopclaid != 0 AND
------+-----------
(0 rows)
SELECT ctid, amopsubtype
FROM pg_catalog.pg_amop fk
WHERE amopsubtype != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
ctid | amopsubtype
------+-------------
(0 rows)
SELECT ctid, amopopr
FROM pg_catalog.pg_amop fk
WHERE amopopr != 0 AND
@@ -145,6 +153,14 @@ WHERE amopclaid != 0 AND
------+-----------
(0 rows)
SELECT ctid, amprocsubtype
FROM pg_catalog.pg_amproc fk
WHERE amprocsubtype != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
ctid | amprocsubtype
------+---------------
(0 rows)
SELECT ctid, amproc
FROM pg_catalog.pg_amproc fk
WHERE amproc != 0 AND

View File

@@ -685,30 +685,61 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
-----------+---------+-----+--------
(0 rows)
-- Detect missing pg_amop entries: should have as many strategy functions
-- as AM expects for each opclass for the AM
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
FROM pg_am AS p1, pg_opclass AS p2
WHERE p2.opcamid = p1.oid AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
WHERE p3.amopclaid = p2.oid);
oid | amname | oid | opcname
-----+--------+-----+---------
-- Detect missing pg_amop entries: should have as many strategy operators
-- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
WHERE p4.amopclaid = p2.oid AND
p4.amopsubtype = p3.amopsubtype);
oid | amname | oid | opcname | amopsubtype
-----+--------+-----+---------+-------------
(0 rows)
-- Check that amopopr points at a reasonable-looking operator, ie a binary
-- operator yielding boolean.
-- NOTE: for 7.1, add restriction that operator inputs are of same type.
-- We used to have opclasses like "int24_ops" but these were broken.
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
amopclaid | amopopr | oid | oprname
-----------+---------+-----+---------
(0 rows)
-- Make a list of all the distinct operator names being used in particular
-- strategy slots. This is a bit hokey, since the list might need to change
-- in future releases, but it's an effective way of spotting mistakes such as
-- swapping two operators within a class.
SELECT DISTINCT opcamid, amopstrategy, oprname
FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
LEFT JOIN pg_operator p3 ON amopopr = p3.oid
ORDER BY 1, 2, 3;
opcamid | amopstrategy | oprname
---------+--------------+---------
402 | 1 | <<
402 | 2 | &<
402 | 3 | &&
402 | 4 | &>
402 | 5 | >>
402 | 6 | ~=
402 | 7 | ~
402 | 8 | @
403 | 1 | <
403 | 1 | ~<~
403 | 2 | <=
403 | 2 | ~<=~
403 | 3 | =
403 | 3 | ~=~
403 | 4 | >=
403 | 4 | ~>=~
403 | 5 | >
403 | 5 | ~>~
405 | 1 | =
405 | 1 | ~=~
(20 rows)
-- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable
-- thing to insist on for all standard datatypes.
@@ -721,11 +752,31 @@ WHERE p1.amopopr = p2.oid AND
(0 rows)
-- Check that operator input types match the opclass
-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
-- When amopsubtype is zero (default), oprright must equal oprleft;
-- when amopsubtype is not zero, oprright must equal amopsubtype.
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
(NOT binary_coercible(p3.opcintype, p2.oprleft) OR
p2.oprleft != p2.oprright);
NOT binary_coercible(p3.opcintype, p2.oprleft);
amopclaid | amopopr | oid | oprname | opcname
-----------+---------+-----+---------+---------
(0 rows)
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
p1.amopsubtype = 0 AND
p2.oprleft != p2.oprright;
amopclaid | amopopr | oid | oprname | opcname
-----------+---------+-----+---------+---------
(0 rows)
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
p1.amopsubtype != 0 AND
p1.amopsubtype != p2.oprright;
amopclaid | amopopr | oid | oprname | opcname
-----------+---------+-----+---------+---------
(0 rows)
@@ -749,14 +800,16 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
(0 rows)
-- Detect missing pg_amproc entries: should have as many support functions
-- as AM expects for each opclass for the AM
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
FROM pg_am AS p1, pg_opclass AS p2
WHERE p2.opcamid = p1.oid AND
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
WHERE p3.amopclaid = p2.oid);
oid | amname | oid | opcname
-----+--------+-----+---------
-- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
WHERE p4.amopclaid = p2.oid AND
p4.amprocsubtype = p3.amprocsubtype);
oid | amname | oid | opcname | amprocsubtype
-----+--------+-----+---------+---------------
(0 rows)
-- Unfortunately, we can't check the amproc link very well because the
@@ -782,13 +835,15 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
(0 rows)
-- For btree, though, we can do better since we know the support routines
-- must be of the form cmp(input, input) returns int4.
-- must be of the form cmp(input, input) returns int4 in the default case
-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
SELECT p1.amopclaid, p1.amprocnum,
p2.oid, p2.proname,
p3.opcname
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
amprocsubtype = 0 AND
(opckeytype != 0
OR amprocnum != 1
OR proretset
@@ -800,6 +855,24 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
-----------+-----------+-----+---------+---------
(0 rows)
SELECT p1.amopclaid, p1.amprocnum,
p2.oid, p2.proname,
p3.opcname
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
amprocsubtype != 0 AND
(opckeytype != 0
OR amprocnum != 1
OR proretset
OR prorettype != 23
OR pronargs != 2
OR NOT binary_coercible(opcintype, proargtypes[0])
OR proargtypes[1] != amprocsubtype);
amopclaid | amprocnum | oid | proname | opcname
-----------+-----------+-----+---------+---------
(0 rows)
-- For hash we can also do a little better: the support routines must be
-- of the form hash(something) returns int4. Ideally we'd check that the
-- opcintype is binary-coercible to the function's input, but there are

View File

@@ -68,7 +68,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
-- in the regression test (we check them using the sequoia 2000
-- benchmark).
--
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
-- there's no easy way to check that this command actually is using
-- the index, unfortunately. (EXPLAIN would work, but its output

View File

@@ -65,6 +65,10 @@ SELECT ctid, amopclaid
FROM pg_catalog.pg_amop fk
WHERE amopclaid != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
SELECT ctid, amopsubtype
FROM pg_catalog.pg_amop fk
WHERE amopsubtype != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
SELECT ctid, amopopr
FROM pg_catalog.pg_amop fk
WHERE amopopr != 0 AND
@@ -73,6 +77,10 @@ SELECT ctid, amopclaid
FROM pg_catalog.pg_amproc fk
WHERE amopclaid != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
SELECT ctid, amprocsubtype
FROM pg_catalog.pg_amproc fk
WHERE amprocsubtype != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
SELECT ctid, amproc
FROM pg_catalog.pg_amproc fk
WHERE amproc != 0 AND

View File

@@ -574,25 +574,34 @@ FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3
WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
p1.amopstrategy > p2.amstrategies;
-- Detect missing pg_amop entries: should have as many strategy functions
-- as AM expects for each opclass for the AM
-- Detect missing pg_amop entries: should have as many strategy operators
-- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
FROM pg_am AS p1, pg_opclass AS p2
WHERE p2.opcamid = p1.oid AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
WHERE p3.amopclaid = p2.oid);
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
WHERE p4.amopclaid = p2.oid AND
p4.amopsubtype = p3.amopsubtype);
-- Check that amopopr points at a reasonable-looking operator, ie a binary
-- operator yielding boolean.
-- NOTE: for 7.1, add restriction that operator inputs are of same type.
-- We used to have opclasses like "int24_ops" but these were broken.
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
-- Make a list of all the distinct operator names being used in particular
-- strategy slots. This is a bit hokey, since the list might need to change
-- in future releases, but it's an effective way of spotting mistakes such as
-- swapping two operators within a class.
SELECT DISTINCT opcamid, amopstrategy, oprname
FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
LEFT JOIN pg_operator p3 ON amopopr = p3.oid
ORDER BY 1, 2, 3;
-- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable
@@ -604,12 +613,26 @@ WHERE p1.amopopr = p2.oid AND
(p2.oprrest = 0 OR p2.oprjoin = 0);
-- Check that operator input types match the opclass
-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
-- When amopsubtype is zero (default), oprright must equal oprleft;
-- when amopsubtype is not zero, oprright must equal amopsubtype.
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
(NOT binary_coercible(p3.opcintype, p2.oprleft) OR
p2.oprleft != p2.oprright);
NOT binary_coercible(p3.opcintype, p2.oprleft);
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
p1.amopsubtype = 0 AND
p2.oprleft != p2.oprright;
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
p1.amopsubtype != 0 AND
p1.amopsubtype != p2.oprright;
-- **************** pg_amproc ****************
@@ -627,13 +650,15 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
p1.amprocnum > p2.amsupport;
-- Detect missing pg_amproc entries: should have as many support functions
-- as AM expects for each opclass for the AM
-- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
FROM pg_am AS p1, pg_opclass AS p2
WHERE p2.opcamid = p1.oid AND
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
WHERE p3.amopclaid = p2.oid);
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
WHERE p4.amopclaid = p2.oid AND
p4.amprocsubtype = p3.amprocsubtype);
-- Unfortunately, we can't check the amproc link very well because the
-- signature of the function may be different for different support routines
@@ -656,7 +681,8 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
(p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);
-- For btree, though, we can do better since we know the support routines
-- must be of the form cmp(input, input) returns int4.
-- must be of the form cmp(input, input) returns int4 in the default case
-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
SELECT p1.amopclaid, p1.amprocnum,
p2.oid, p2.proname,
@@ -664,6 +690,7 @@ SELECT p1.amopclaid, p1.amprocnum,
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
amprocsubtype = 0 AND
(opckeytype != 0
OR amprocnum != 1
OR proretset
@@ -672,6 +699,21 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
OR NOT binary_coercible(opcintype, proargtypes[0])
OR proargtypes[0] != proargtypes[1]);
SELECT p1.amopclaid, p1.amprocnum,
p2.oid, p2.proname,
p3.opcname
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
amprocsubtype != 0 AND
(opckeytype != 0
OR amprocnum != 1
OR proretset
OR prorettype != 23
OR pronargs != 2
OR NOT binary_coercible(opcintype, proargtypes[0])
OR proargtypes[1] != amprocsubtype);
-- For hash we can also do a little better: the support routines must be
-- of the form hash(something) returns int4. Ideally we'd check that the
-- opcintype is binary-coercible to the function's input, but there are