Skip to content

Commit a0a0512

Browse files
committed
Disallow changing DEFAULT expression of a SERIAL column.
Dhanaraj M
1 parent 908f317 commit a0a0512

File tree

5 files changed

+149
-5
lines changed

5 files changed

+149
-5
lines changed

src/backend/catalog/dependency.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.51 2006/03/16 00:31:54 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.52 2006/04/29 16:43:54 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1931,3 +1931,89 @@ getRelationDescription(StringInfo buffer, Oid relid)
19311931

19321932
ReleaseSysCache(relTup);
19331933
}
1934+
1935+
/* Recursively travel and search for the default sequence. Finally detach it */
1936+
1937+
void performSequenceDefaultDeletion(const ObjectAddress *object,
1938+
DropBehavior behavior, int deleteFlag)
1939+
{
1940+
1941+
ScanKeyData key[3];
1942+
int nkeys;
1943+
SysScanDesc scan;
1944+
HeapTuple tup;
1945+
ObjectAddress otherObject;
1946+
Relation depRel;
1947+
1948+
depRel = heap_open(DependRelationId, RowExclusiveLock);
1949+
1950+
ScanKeyInit(&key[0],
1951+
Anum_pg_depend_classid,
1952+
BTEqualStrategyNumber, F_OIDEQ,
1953+
ObjectIdGetDatum(object->classId));
1954+
ScanKeyInit(&key[1],
1955+
Anum_pg_depend_objid,
1956+
BTEqualStrategyNumber, F_OIDEQ,
1957+
ObjectIdGetDatum(object->objectId));
1958+
if (object->objectSubId != 0)
1959+
{
1960+
ScanKeyInit(&key[2],
1961+
Anum_pg_depend_objsubid,
1962+
BTEqualStrategyNumber, F_INT4EQ,
1963+
Int32GetDatum(object->objectSubId));
1964+
nkeys = 3;
1965+
}
1966+
else
1967+
nkeys = 2;
1968+
1969+
scan = systable_beginscan(depRel, DependDependerIndexId, true,
1970+
SnapshotNow, nkeys, key);
1971+
1972+
while (HeapTupleIsValid(tup = systable_getnext(scan)))
1973+
{
1974+
1975+
Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
1976+
1977+
otherObject.classId = foundDep->refclassid;
1978+
otherObject.objectId = foundDep->refobjid;
1979+
otherObject.objectSubId = foundDep->refobjsubid;
1980+
1981+
/* Detach the default sequence from the relation */
1982+
if(deleteFlag == 1)
1983+
{
1984+
simple_heap_delete(depRel, &tup->t_self);
1985+
break;
1986+
}
1987+
1988+
switch (foundDep->deptype)
1989+
{
1990+
case DEPENDENCY_NORMAL:
1991+
{
1992+
1993+
if(getObjectClass(&otherObject) == OCLASS_CLASS)
1994+
{
1995+
/* Dont allow to change the default sequence */
1996+
if(deleteFlag == 2)
1997+
{
1998+
systable_endscan(scan);
1999+
heap_close(depRel, RowExclusiveLock);
2000+
elog(ERROR, "%s is a SERIAL sequence. Can't alter the relation", getObjectDescription(&otherObject));
2001+
return;
2002+
}
2003+
else /* Detach the default sequence from the relation */
2004+
{
2005+
performSequenceDefaultDeletion(&otherObject, behavior, 1);
2006+
systable_endscan(scan);
2007+
heap_close(depRel, RowExclusiveLock);
2008+
return;
2009+
}
2010+
}
2011+
}
2012+
2013+
}
2014+
}
2015+
2016+
systable_endscan(scan);
2017+
heap_close(depRel, RowExclusiveLock);
2018+
2019+
}

src/backend/catalog/heap.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.296 2006/04/24 01:40:48 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.297 2006/04/29 16:43:54 momjian Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2136,3 +2136,50 @@ heap_truncate_find_FKs(List *relationIds)
21362136

21372137
return result;
21382138
}
2139+
2140+
2141+
/* Detach the default sequence and the relation */
2142+
2143+
void
2144+
RemoveSequenceDefault(Oid relid, AttrNumber attnum,
2145+
DropBehavior behavior, bool flag)
2146+
{
2147+
Relation attrdef_rel;
2148+
ScanKeyData scankeys[2];
2149+
SysScanDesc scan;
2150+
HeapTuple tuple;
2151+
2152+
attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
2153+
2154+
ScanKeyInit(&scankeys[0],
2155+
Anum_pg_attrdef_adrelid,
2156+
BTEqualStrategyNumber, F_OIDEQ,
2157+
ObjectIdGetDatum(relid));
2158+
ScanKeyInit(&scankeys[1],
2159+
Anum_pg_attrdef_adnum,
2160+
BTEqualStrategyNumber, F_INT2EQ,
2161+
Int16GetDatum(attnum));
2162+
2163+
scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
2164+
SnapshotNow, 2, scankeys);
2165+
2166+
/* There should be at most one matching tuple, but we loop anyway */
2167+
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2168+
{
2169+
ObjectAddress object;
2170+
2171+
object.classId = AttrDefaultRelationId;
2172+
object.objectId = HeapTupleGetOid(tuple);
2173+
object.objectSubId = 0;
2174+
2175+
if(flag == true) /* Detach the sequence */
2176+
performSequenceDefaultDeletion(&object, behavior, 0);
2177+
else /* Don't allow to change the default sequence */
2178+
performSequenceDefaultDeletion(&object, behavior, 2);
2179+
2180+
}
2181+
2182+
systable_endscan(scan);
2183+
heap_close(attrdef_rel, RowExclusiveLock);
2184+
2185+
}

src/backend/commands/tablecmds.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.181 2006/03/14 22:48:18 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.182 2006/04/29 16:43:54 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -3362,6 +3362,11 @@ ATExecColumnDefault(Relation rel, const char *colName,
33623362
* safety, but at present we do not expect anything to depend on the
33633363
* default.
33643364
*/
3365+
if (newDefault)
3366+
RemoveSequenceDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
3367+
else
3368+
RemoveSequenceDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
3369+
33653370
RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
33663371

33673372
if (newDefault)

src/include/catalog/dependency.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.21 2006/03/05 15:58:54 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.22 2006/04/29 16:43:54 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -207,4 +207,7 @@ extern void shdepDropOwned(List *relids, DropBehavior behavior);
207207

208208
extern void shdepReassignOwned(List *relids, Oid newrole);
209209

210+
extern void performSequenceDefaultDeletion(const ObjectAddress *object,
211+
DropBehavior behavior, int deleteFlag);
212+
210213
#endif /* DEPENDENCY_H */

src/include/catalog/heap.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.78 2006/03/05 15:58:54 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.79 2006/04/29 16:43:54 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -97,4 +97,7 @@ extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind);
9797

9898
extern void CheckAttributeType(const char *attname, Oid atttypid);
9999

100+
extern void RemoveSequenceDefault(Oid relid, AttrNumber attnum,
101+
DropBehavior behavior, bool flag);
102+
100103
#endif /* HEAP_H */

0 commit comments

Comments
 (0)