Commit 92a30a7e authored by Tom Lane's avatar Tom Lane

Fix broken dependency-mongering for index operator classes/families.

For a long time, opclasscmds.c explained that "we do not create a
dependency link to the AM [for an opclass or opfamily], because we don't
currently support DROP ACCESS METHOD".  Commit 473b9328 invented
DROP ACCESS METHOD, but it batted only 1 for 2 on adding the dependency
links, and 0 for 2 on updating the comments about the topic.

In passing, undo the same commit's entirely inappropriate decision to
blow away an existing index as a side-effect of create_am.sql.
parent c8cb7453
...@@ -285,14 +285,18 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) ...@@ -285,14 +285,18 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
heap_freetuple(tup); heap_freetuple(tup);
/* /*
* Create dependencies for the opfamily proper. Note: we do not create a * Create dependencies for the opfamily proper.
* dependency link to the AM, because we don't currently support DROP
* ACCESS METHOD.
*/ */
myself.classId = OperatorFamilyRelationId; myself.classId = OperatorFamilyRelationId;
myself.objectId = opfamilyoid; myself.objectId = opfamilyoid;
myself.objectSubId = 0; myself.objectSubId = 0;
/* dependency on access method */
referenced.classId = AccessMethodRelationId;
referenced.objectId = amoid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
/* dependency on namespace */ /* dependency on namespace */
referenced.classId = NamespaceRelationId; referenced.classId = NamespaceRelationId;
referenced.objectId = namespaceoid; referenced.objectId = namespaceoid;
...@@ -670,20 +674,13 @@ DefineOpClass(CreateOpClassStmt *stmt) ...@@ -670,20 +674,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
EventTriggerCollectCreateOpClass(stmt, opclassoid, operators, procedures); EventTriggerCollectCreateOpClass(stmt, opclassoid, operators, procedures);
/* /*
* Create dependencies for the opclass proper. Note: we do not create a * Create dependencies for the opclass proper. Note: we do not need a
* dependency link to the AM, because we don't currently support DROP * dependency link to the AM, because that exists through the opfamily.
* ACCESS METHOD.
*/ */
myself.classId = OperatorClassRelationId; myself.classId = OperatorClassRelationId;
myself.objectId = opclassoid; myself.objectId = opclassoid;
myself.objectSubId = 0; myself.objectSubId = 0;
/* dependency on access method */
referenced.classId = AccessMethodRelationId;
referenced.objectId = amoid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* dependency on namespace */ /* dependency on namespace */
referenced.classId = NamespaceRelationId; referenced.classId = NamespaceRelationId;
referenced.objectId = namespaceoid; referenced.objectId = namespaceoid;
......
...@@ -3,10 +3,8 @@ ...@@ -3,10 +3,8 @@
-- --
-- Make gist2 over gisthandler. In fact, it would be a synonym to gist. -- Make gist2 over gisthandler. In fact, it would be a synonym to gist.
CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler; CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;
-- Drop old index on fast_emp4000
DROP INDEX grect2ind;
-- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist -- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist
CREATE INDEX grect2ind ON fast_emp4000 USING gist2 (home_base); CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base);
ERROR: data type box has no default operator class for access method "gist2" ERROR: data type box has no default operator class for access method "gist2"
HINT: You must specify an operator class for the index or define a default operator class for the data type. HINT: You must specify an operator class for the index or define a default operator class for the data type.
-- Make operator class for boxes using gist2 -- Make operator class for boxes using gist2
...@@ -35,8 +33,11 @@ CREATE OPERATOR CLASS box_ops DEFAULT ...@@ -35,8 +33,11 @@ CREATE OPERATOR CLASS box_ops DEFAULT
FUNCTION 7 gist_box_same(box, box, internal), FUNCTION 7 gist_box_same(box, box, internal),
FUNCTION 9 gist_box_fetch(internal); FUNCTION 9 gist_box_fetch(internal);
-- Create gist2 index on fast_emp4000 -- Create gist2 index on fast_emp4000
CREATE INDEX grect2ind ON fast_emp4000 USING gist2 (home_base); CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base);
-- Now check the results from plain indexscan -- Now check the results from plain indexscan; temporarily drop existing
-- index grect2ind to ensure it doesn't capture the plan
BEGIN;
DROP INDEX grect2ind;
SET enable_seqscan = OFF; SET enable_seqscan = OFF;
SET enable_indexscan = ON; SET enable_indexscan = ON;
SET enable_bitmapscan = OFF; SET enable_bitmapscan = OFF;
...@@ -48,7 +49,7 @@ SELECT * FROM fast_emp4000 ...@@ -48,7 +49,7 @@ SELECT * FROM fast_emp4000
---------------------------------------------------------------- ----------------------------------------------------------------
Sort Sort
Sort Key: ((home_base[0])[0]) Sort Key: ((home_base[0])[0])
-> Index Only Scan using grect2ind on fast_emp4000 -> Index Only Scan using grect2ind2 on fast_emp4000
Index Cond: (home_base @ '(2000,1000),(200,200)'::box) Index Cond: (home_base @ '(2000,1000),(200,200)'::box)
(4 rows) (4 rows)
...@@ -66,7 +67,7 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; ...@@ -66,7 +67,7 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
QUERY PLAN QUERY PLAN
------------------------------------------------------------- -------------------------------------------------------------
Aggregate Aggregate
-> Index Only Scan using grect2ind on fast_emp4000 -> Index Only Scan using grect2ind2 on fast_emp4000
Index Cond: (home_base && '(1000,1000),(0,0)'::box) Index Cond: (home_base && '(1000,1000),(0,0)'::box)
(3 rows) (3 rows)
...@@ -78,10 +79,10 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; ...@@ -78,10 +79,10 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
QUERY PLAN QUERY PLAN
------------------------------------------------------- --------------------------------------------------------
Aggregate Aggregate
-> Index Only Scan using grect2ind on fast_emp4000 -> Index Only Scan using grect2ind2 on fast_emp4000
Index Cond: (home_base IS NULL) Index Cond: (home_base IS NULL)
(3 rows) (3 rows)
...@@ -91,18 +92,12 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; ...@@ -91,18 +92,12 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
278 278
(1 row) (1 row)
-- Try to drop access method: fail because of depending objects ROLLBACK;
-- Try to drop access method: fail because of dependent objects
DROP ACCESS METHOD gist2; DROP ACCESS METHOD gist2;
ERROR: cannot drop access method gist2 because other objects depend on it ERROR: cannot drop access method gist2 because other objects depend on it
DETAIL: operator class box_ops for access method gist2 depends on access method gist2 DETAIL: index grect2ind2 depends on operator class box_ops for access method gist2
index grect2ind depends on operator class box_ops for access method gist2
HINT: Use DROP ... CASCADE to drop the dependent objects too. HINT: Use DROP ... CASCADE to drop the dependent objects too.
-- Drop access method cascade -- Drop access method cascade
DROP ACCESS METHOD gist2 CASCADE; DROP ACCESS METHOD gist2 CASCADE;
NOTICE: drop cascades to 2 other objects NOTICE: drop cascades to index grect2ind2
DETAIL: drop cascades to operator class box_ops for access method gist2
drop cascades to index grect2ind
-- Reset optimizer options
RESET enable_seqscan;
RESET enable_indexscan;
RESET enable_bitmapscan;
...@@ -44,7 +44,7 @@ e_star|f ...@@ -44,7 +44,7 @@ e_star|f
emp|f emp|f
equipment_r|f equipment_r|f
f_star|f f_star|f
fast_emp4000|f fast_emp4000|t
float4_tbl|f float4_tbl|f
float8_tbl|f float8_tbl|f
func_index_heap|t func_index_heap|t
......
...@@ -5,11 +5,8 @@ ...@@ -5,11 +5,8 @@
-- Make gist2 over gisthandler. In fact, it would be a synonym to gist. -- Make gist2 over gisthandler. In fact, it would be a synonym to gist.
CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler; CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;
-- Drop old index on fast_emp4000
DROP INDEX grect2ind;
-- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist -- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist
CREATE INDEX grect2ind ON fast_emp4000 USING gist2 (home_base); CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base);
-- Make operator class for boxes using gist2 -- Make operator class for boxes using gist2
CREATE OPERATOR CLASS box_ops DEFAULT CREATE OPERATOR CLASS box_ops DEFAULT
...@@ -38,9 +35,12 @@ CREATE OPERATOR CLASS box_ops DEFAULT ...@@ -38,9 +35,12 @@ CREATE OPERATOR CLASS box_ops DEFAULT
FUNCTION 9 gist_box_fetch(internal); FUNCTION 9 gist_box_fetch(internal);
-- Create gist2 index on fast_emp4000 -- Create gist2 index on fast_emp4000
CREATE INDEX grect2ind ON fast_emp4000 USING gist2 (home_base); CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base);
-- Now check the results from plain indexscan -- Now check the results from plain indexscan; temporarily drop existing
-- index grect2ind to ensure it doesn't capture the plan
BEGIN;
DROP INDEX grect2ind;
SET enable_seqscan = OFF; SET enable_seqscan = OFF;
SET enable_indexscan = ON; SET enable_indexscan = ON;
SET enable_bitmapscan = OFF; SET enable_bitmapscan = OFF;
...@@ -61,13 +61,10 @@ EXPLAIN (COSTS OFF) ...@@ -61,13 +61,10 @@ EXPLAIN (COSTS OFF)
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
-- Try to drop access method: fail because of depending objects ROLLBACK;
-- Try to drop access method: fail because of dependent objects
DROP ACCESS METHOD gist2; DROP ACCESS METHOD gist2;
-- Drop access method cascade -- Drop access method cascade
DROP ACCESS METHOD gist2 CASCADE; DROP ACCESS METHOD gist2 CASCADE;
-- Reset optimizer options
RESET enable_seqscan;
RESET enable_indexscan;
RESET enable_bitmapscan;
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