Re: Tentative patch for making DROP put dependency info in DETAIL
"Alex Hunsaker" <[email protected]>
| Newsgroups | gmane.comp.db.postgresql.devel.patches |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Jun 11, 2008 at 4:07 PM, Tom Lane <[email protected]> wrote: > Agreed --- I committed what I had, anyone want to volunteer for > refactoring the execution of DropStmt? Sure! see the attached patch... > After looking again, I think that this is not technically very > difficult, but coming up with something that looks tasteful to everyone > might be tricky. In particular I didn't see a nice way to do it without > using struct ObjectAddress in a bunch of header files that don't > currently include dependency.h. A possible response to that is to move > ObjectAddress into postgres.h, but that seems a bit ugly too. Ok I'm obviously missing something important... Why not Just make the various Remove* functions take a list? I'm not proposing this patch for actual submission, more of a would this work? If I'm not missing something glaring obvious Ill go ahead and make the rest of the Remove things behave the same way -- Sent via pgsql-patches mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches
dropStmt_mutlidelete.patch
(application/octet-stream, 7.4 KB)
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 4a9ad9c..2e4c9b9 100644
*** a/src/backend/catalog/dependency.c
--- /bsrc/backend/catalog/dependency.c
*************** performMultipleDeletions(const ObjectAdd
*** 257,262 ****
--- 257,263 ----
{
Relation depRel;
ObjectAddresses *targetObjects;
+ ObjectAddress *depObject;
int i;
/*
*************** performMultipleDeletions(const ObjectAdd
*** 294,305 ****
}
/*
* Check if deletion is allowed, and report about cascaded deletes.
*/
reportDependentObjects(targetObjects,
behavior,
NOTICE,
! NULL);
/*
* Delete all the objects in the proper order.
--- 295,312 ----
}
/*
+ * If we are only deleting one object report it like we do
+ * in performDeletion()
+ */
+ depObject = objects->numrefs == 1 ? objects->refs : NULL;
+
+ /*
* Check if deletion is allowed, and report about cascaded deletes.
*/
reportDependentObjects(targetObjects,
behavior,
NOTICE,
! depObject);
/*
* Delete all the objects in the proper order.
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c3ff499..3e898d9 100644
*** a/src/backend/commands/tablecmds.c
--- /bsrc/backend/commands/tablecmds.c
*************** DefineRelation(CreateStmt *stmt, char re
*** 499,518 ****
/*
* RemoveRelation
* Deletes a relation.
*/
void
! RemoveRelation(const RangeVar *relation, DropBehavior behavior)
{
! Oid relOid;
! ObjectAddress object;
! relOid = RangeVarGetRelid(relation, false);
! object.classId = RelationRelationId;
! object.objectId = relOid;
! object.objectSubId = 0;
! performDeletion(&object, behavior);
}
/*
--- 499,529 ----
/*
* RemoveRelation
* Deletes a relation.
+ * Note rels are of the type RangeVar *
*/
void
! RemoveRelation(List *rels, const DropBehavior behavior)
{
! ObjectAddresses *objects;
! ListCell *cell;
! objects = new_object_addresses();
! foreach(cell, rels)
! {
! RangeVar *rv = lfirst(cell);
! ObjectAddress obj;
! obj.objectId = RangeVarGetRelid(rv, false);
! obj.classId = RelationRelationId;
! obj.objectSubId = 0;
!
! add_exact_object_address(&obj, objects);
! }
!
! performMultipleDeletions(objects, behavior);
!
! free_object_addresses(objects);
}
/*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 5d37d57..5cf44a5 100644
*** a/src/backend/tcop/utility.c
--- /bsrc/backend/tcop/utility.c
*************** ProcessUtility(Node *parsetree,
*** 605,610 ****
--- 605,616 ----
DropStmt *stmt = (DropStmt *) parsetree;
ListCell *arg;
+ /*
+ * We aggregate any calls to RemoveRelation
+ * so that it can use performMultipleDeletions()
+ */
+ List *removeRels = NULL;
+
foreach(arg, stmt->objects)
{
List *names = (List *) lfirst(arg);
*************** ProcessUtility(Node *parsetree,
*** 616,629 ****
rel = makeRangeVarFromNameList(names);
if (CheckDropPermissions(rel, RELKIND_RELATION,
stmt->missing_ok))
! RemoveRelation(rel, stmt->behavior);
break;
case OBJECT_SEQUENCE:
rel = makeRangeVarFromNameList(names);
if (CheckDropPermissions(rel, RELKIND_SEQUENCE,
stmt->missing_ok))
! RemoveRelation(rel, stmt->behavior);
break;
case OBJECT_VIEW:
--- 622,635 ----
rel = makeRangeVarFromNameList(names);
if (CheckDropPermissions(rel, RELKIND_RELATION,
stmt->missing_ok))
! removeRels = lappend(removeRels, rel);
break;
case OBJECT_SEQUENCE:
rel = makeRangeVarFromNameList(names);
if (CheckDropPermissions(rel, RELKIND_SEQUENCE,
stmt->missing_ok))
! removeRels = lappend(removeRels, rel);
break;
case OBJECT_VIEW:
*************** ProcessUtility(Node *parsetree,
*** 694,699 ****
--- 700,708 ----
* but now it's done inside performDeletion().
*/
}
+
+ if (removeRels)
+ RemoveRelation(removeRels, stmt->behavior);
}
break;
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index d89a356..f8e2ff3 100644
*** a/src/include/commands/tablecmds.h
--- /bsrc/include/commands/tablecmds.h
***************
*** 20,26 ****
extern Oid DefineRelation(CreateStmt *stmt, char relkind);
! extern void RemoveRelation(const RangeVar *relation, DropBehavior behavior);
extern void AlterTable(AlterTableStmt *stmt);
--- 20,26 ----
extern Oid DefineRelation(CreateStmt *stmt, char relkind);
! extern void RemoveRelation(List *rels, const DropBehavior behavior);
extern void AlterTable(AlterTableStmt *stmt);
diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out
index e3086d2..566c5d3 100644
*** a/src/test/regress/expected/foreign_key.out
--- /bsrc/test/regress/expected/foreign_key.out
*************** COMMIT;
*** 1087,1093 ****
ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
DETAIL: Key (fk)=(200) is not present in table "pktable".
DROP TABLE pktable, fktable CASCADE;
- NOTICE: drop cascades to constraint fktable_fk_fkey on table fktable
-- test notice about expensive referential integrity checks,
-- where the index cannot be used because of type incompatibilities.
CREATE TEMP TABLE pktable (
--- 1087,1092 ----
*************** FOREIGN KEY (x2,x4,x1) REFERENCES pktabl
*** 1157,1172 ****
ERROR: foreign key constraint "fk_241_132" cannot be implemented
DETAIL: Key columns "x2" and "id1" are of incompatible types: character varying and integer.
DROP TABLE pktable, fktable CASCADE;
- NOTICE: drop cascades to 9 other objects
- DETAIL: drop cascades to constraint fktable_x3_fkey on table fktable
- drop cascades to constraint fk_1_3 on table fktable
- drop cascades to constraint fktable_x2_fkey on table fktable
- drop cascades to constraint fk_4_2 on table fktable
- drop cascades to constraint fktable_x1_fkey on table fktable
- drop cascades to constraint fk_5_1 on table fktable
- drop cascades to constraint fk_123_123 on table fktable
- drop cascades to constraint fk_213_213 on table fktable
- drop cascades to constraint fk_253_213 on table fktable
-- test a tricky case: we can elide firing the FK check trigger during
-- an UPDATE if the UPDATE did not change the foreign key
-- field. However, we can't do this if our transaction was the one that
--- 1156,1161 ----
diff --git a/src/test/regress/expected/truncate.out b/src/test/regress/expected/truncate.out
index 520db9d..c9134ee 100644
*** a/src/test/regress/expected/truncate.out
--- /bsrc/test/regress/expected/truncate.out
*************** SELECT * FROM trunc_e;
*** 141,152 ****
(0 rows)
DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE;
- NOTICE: drop cascades to 2 other objects
- DETAIL: drop cascades to constraint trunc_b_a_fkey on table trunc_b
- drop cascades to constraint trunc_e_a_fkey on table trunc_e
- NOTICE: drop cascades to 2 other objects
- DETAIL: drop cascades to constraint trunc_d_a_fkey on table trunc_d
- drop cascades to constraint trunc_e_b_fkey on table trunc_e
-- Test ON TRUNCATE triggers
CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text);
CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text,
--- 141,146 ----