Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2016-04-14 03:33:31 +0000
committerTom Lane2016-04-14 03:33:31 +0000
commit92a30a7eb0cadb008e18053f199af7de3fc1abaa (patch)
tree6c755da85fbfe8bbc896fd98b1655d8b8a32df42
parentc8cb7453233b31a177b08a3b2bdac4c31508dc00 (diff)
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 473b93287040b200 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.
-rw-r--r--src/backend/commands/opclasscmds.c21
-rw-r--r--src/test/regress/expected/create_am.out35
-rw-r--r--src/test/regress/expected/sanity_check.out2
-rw-r--r--src/test/regress/sql/create_am.sql21
4 files changed, 34 insertions, 45 deletions
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index ac559fc9b41..5f665cf3a20 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -285,14 +285,18 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
heap_freetuple(tup);
/*
- * Create dependencies for the opfamily proper. Note: we do not create a
- * dependency link to the AM, because we don't currently support DROP
- * ACCESS METHOD.
+ * Create dependencies for the opfamily proper.
*/
myself.classId = OperatorFamilyRelationId;
myself.objectId = opfamilyoid;
myself.objectSubId = 0;
+ /* dependency on access method */
+ referenced.classId = AccessMethodRelationId;
+ referenced.objectId = amoid;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
+
/* dependency on namespace */
referenced.classId = NamespaceRelationId;
referenced.objectId = namespaceoid;
@@ -670,20 +674,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
EventTriggerCollectCreateOpClass(stmt, opclassoid, operators, procedures);
/*
- * Create dependencies for the opclass proper. Note: we do not create a
- * dependency link to the AM, because we don't currently support DROP
- * ACCESS METHOD.
+ * Create dependencies for the opclass proper. Note: we do not need a
+ * dependency link to the AM, because that exists through the opfamily.
*/
myself.classId = OperatorClassRelationId;
myself.objectId = opclassoid;
myself.objectSubId = 0;
- /* dependency on access method */
- referenced.classId = AccessMethodRelationId;
- referenced.objectId = amoid;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
/* dependency on namespace */
referenced.classId = NamespaceRelationId;
referenced.objectId = namespaceoid;
diff --git a/src/test/regress/expected/create_am.out b/src/test/regress/expected/create_am.out
index 47d6024610d..1b464aae2dc 100644
--- a/src/test/regress/expected/create_am.out
+++ b/src/test/regress/expected/create_am.out
@@ -3,10 +3,8 @@
--
-- Make gist2 over gisthandler. In fact, it would be a synonym to gist.
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
-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"
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
@@ -35,8 +33,11 @@ CREATE OPERATOR CLASS box_ops DEFAULT
FUNCTION 7 gist_box_same(box, box, internal),
FUNCTION 9 gist_box_fetch(internal);
-- Create gist2 index on fast_emp4000
-CREATE INDEX grect2ind ON fast_emp4000 USING gist2 (home_base);
--- Now check the results from plain indexscan
+CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base);
+-- 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_indexscan = ON;
SET enable_bitmapscan = OFF;
@@ -48,7 +49,7 @@ SELECT * FROM fast_emp4000
----------------------------------------------------------------
Sort
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)
(4 rows)
@@ -66,7 +67,7 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
QUERY PLAN
-------------------------------------------------------------
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)
(3 rows)
@@ -78,10 +79,10 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
EXPLAIN (COSTS OFF)
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
- QUERY PLAN
--------------------------------------------------------
+ QUERY PLAN
+--------------------------------------------------------
Aggregate
- -> Index Only Scan using grect2ind on fast_emp4000
+ -> Index Only Scan using grect2ind2 on fast_emp4000
Index Cond: (home_base IS NULL)
(3 rows)
@@ -91,18 +92,12 @@ SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
278
(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;
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
-index grect2ind depends on operator class box_ops for access method gist2
+DETAIL: index grect2ind2 depends on operator class box_ops for access method gist2
HINT: Use DROP ... CASCADE to drop the dependent objects too.
-- Drop access method cascade
DROP ACCESS METHOD gist2 CASCADE;
-NOTICE: drop cascades to 2 other objects
-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;
+NOTICE: drop cascades to index grect2ind2
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 4d81ba7dac2..1c087a39035 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -44,7 +44,7 @@ e_star|f
emp|f
equipment_r|f
f_star|f
-fast_emp4000|f
+fast_emp4000|t
float4_tbl|f
float8_tbl|f
func_index_heap|t
diff --git a/src/test/regress/sql/create_am.sql b/src/test/regress/sql/create_am.sql
index e2051c5fcd3..2f116d98c77 100644
--- a/src/test/regress/sql/create_am.sql
+++ b/src/test/regress/sql/create_am.sql
@@ -5,11 +5,8 @@
-- Make gist2 over gisthandler. In fact, it would be a synonym to gist.
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
-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
CREATE OPERATOR CLASS box_ops DEFAULT
@@ -38,9 +35,12 @@ CREATE OPERATOR CLASS box_ops DEFAULT
FUNCTION 9 gist_box_fetch(internal);
-- 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_indexscan = ON;
SET enable_bitmapscan = 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;
--- 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 cascade
DROP ACCESS METHOD gist2 CASCADE;
-
--- Reset optimizer options
-RESET enable_seqscan;
-RESET enable_indexscan;
-RESET enable_bitmapscan;