mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Disallow changing DEFAULT expression of a SERIAL column.
Dhanaraj M
This commit is contained in:
parent
908f317b73
commit
a0a0512182
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.51 2006/03/16 00:31:54 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.52 2006/04/29 16:43:54 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1931,3 +1931,89 @@ getRelationDescription(StringInfo buffer, Oid relid)
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.296 2006/04/24 01:40:48 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.297 2006/04/29 16:43:54 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -2136,3 +2136,50 @@ heap_truncate_find_FKs(List *relationIds)
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.181 2006/03/14 22:48:18 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.182 2006/04/29 16:43:54 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -3362,6 +3362,11 @@ ATExecColumnDefault(Relation rel, const char *colName,
|
||||
* 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)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* 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.21 2006/03/05 15:58:54 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.22 2006/04/29 16:43:54 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -207,4 +207,7 @@ extern void shdepDropOwned(List *relids, DropBehavior behavior);
|
||||
|
||||
extern void shdepReassignOwned(List *relids, Oid newrole);
|
||||
|
||||
extern void performSequenceDefaultDeletion(const ObjectAddress *object,
|
||||
DropBehavior behavior, int deleteFlag);
|
||||
|
||||
#endif /* DEPENDENCY_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* 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.78 2006/03/05 15:58:54 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.79 2006/04/29 16:43:54 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -97,4 +97,7 @@ extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind);
|
||||
|
||||
extern void CheckAttributeType(const char *attname, Oid atttypid);
|
||||
|
||||
extern void RemoveSequenceDefault(Oid relid, AttrNumber attnum,
|
||||
DropBehavior behavior, bool flag);
|
||||
|
||||
#endif /* HEAP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user