* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.54 2006/05/28 02:27:08 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.55 2006/06/27 03:21:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
ReleaseSysCache(relTup);
}
+
+/* Recursively travel and search for the default sequence. Finally detach it */
+
+void performSequenceDefaultDeletion(const ObjectAddress *object,
+ DropBehavior behavior, int deleteFlag)
+{
+
+ ScanKeyData key[3];
+ int nkeys;
+ SysScanDesc scan;
+ HeapTuple tup;
+ ObjectAddress otherObject;
+ Relation depRel;
+
+ depRel = heap_open(DependRelationId, RowExclusiveLock);
+
+ ScanKeyInit(&key[0],
+ Anum_pg_depend_classid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->classId));
+ ScanKeyInit(&key[1],
+ Anum_pg_depend_objid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+ if (object->objectSubId != 0)
+ {
+ ScanKeyInit(&key[2],
+ Anum_pg_depend_objsubid,
+ BTEqualStrategyNumber, F_INT4EQ,
+ Int32GetDatum(object->objectSubId));
+ nkeys = 3;
+ }
+ else
+ nkeys = 2;
+
+ scan = systable_beginscan(depRel, DependDependerIndexId, true,
+ SnapshotNow, nkeys, key);
+
+ while (HeapTupleIsValid(tup = systable_getnext(scan)))
+ {
+
+ Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
+
+ otherObject.classId = foundDep->refclassid;
+ otherObject.objectId = foundDep->refobjid;
+ otherObject.objectSubId = foundDep->refobjsubid;
+
+ /* Detach the default sequence from the relation */
+ if(deleteFlag == 1)
+ {
+ simple_heap_delete(depRel, &tup->t_self);
+ break;
+ }
+
+ switch (foundDep->deptype)
+ {
+ case DEPENDENCY_NORMAL:
+ {
+
+ if(getObjectClass(&otherObject) == OCLASS_CLASS)
+ {
+ /* Dont allow to change the default sequence */
+ if(deleteFlag == 2)
+ {
+ systable_endscan(scan);
+ heap_close(depRel, RowExclusiveLock);
+ elog(ERROR, "%s is a SERIAL sequence. Can't alter the relation", getObjectDescription(&otherObject));
+ return;
+ }
+ else /* Detach the default sequence from the relation */
+ {
+ performSequenceDefaultDeletion(&otherObject, behavior, 1);
+ systable_endscan(scan);
+ heap_close(depRel, RowExclusiveLock);
+ return;
+ }
+ }
+ }
+
+ }
+ }
+
+ systable_endscan(scan);
+ heap_close(depRel, RowExclusiveLock);
+
+}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.299 2006/05/10 23:18:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.300 2006/06/27 03:21:54 momjian Exp $
*
*
* INTERFACE ROUTINES
return result;
}
+
+
+/* Detach the default sequence and the relation */
+
+void
+RemoveSequenceDefault(Oid relid, AttrNumber attnum,
+ DropBehavior behavior, bool flag)
+{
+ Relation attrdef_rel;
+ ScanKeyData scankeys[2];
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
+
+ ScanKeyInit(&scankeys[0],
+ Anum_pg_attrdef_adrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(relid));
+ ScanKeyInit(&scankeys[1],
+ Anum_pg_attrdef_adnum,
+ BTEqualStrategyNumber, F_INT2EQ,
+ Int16GetDatum(attnum));
+
+ scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
+ SnapshotNow, 2, scankeys);
+
+ /* There should be at most one matching tuple, but we loop anyway */
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ ObjectAddress object;
+
+ object.classId = AttrDefaultRelationId;
+ object.objectId = HeapTupleGetOid(tuple);
+ object.objectSubId = 0;
+
+ if(flag == true) /* Detach the sequence */
+ performSequenceDefaultDeletion(&object, behavior, 0);
+ else /* Don't allow to change the default sequence */
+ performSequenceDefaultDeletion(&object, behavior, 2);
+
+ }
+
+ systable_endscan(scan);
+ heap_close(attrdef_rel, RowExclusiveLock);
+
+}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.185 2006/06/16 18:42:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.186 2006/06/27 03:21:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* safety, but at present we do not expect anything to depend on the
* default.
*/
+ if (newDefault)
+ RemoveSequenceDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
+ else
+ RemoveSequenceDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
+
RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
if (newDefault)
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.23 2006/04/30 01:08:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.24 2006/06/27 03:21:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern void shdepReassignOwned(List *relids, Oid newrole);
+extern void performSequenceDefaultDeletion(const ObjectAddress *object,
+ DropBehavior behavior, int deleteFlag);
+
#endif /* DEPENDENCY_H */
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.80 2006/04/30 01:08:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.81 2006/06/27 03:21:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern void CheckAttributeType(const char *attname, Oid atttypid);
+extern void RemoveSequenceDefault(Oid relid, AttrNumber attnum,
+ DropBehavior behavior, bool flag);
+
#endif /* HEAP_H */