|
8 | 8 | * Portions Copyright (c) 1994, Regents of the University of California |
9 | 9 | * |
10 | 10 | * 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 $ |
12 | 12 | * |
13 | 13 | *------------------------------------------------------------------------- |
14 | 14 | */ |
@@ -1931,3 +1931,89 @@ getRelationDescription(StringInfo buffer, Oid relid) |
1931 | 1931 |
|
1932 | 1932 | ReleaseSysCache(relTup); |
1933 | 1933 | } |
| 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 | +} |
0 commit comments