> For me, it's better to prevent that from happening. So, attempts to > DROP NOT NULL on the child must be rejected. The attached patch does > that.
I'm sorry. Accidentaly i "--color"-ed the patch format. Attached the correct patch. Best Regards, Ali Akbar
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c index 1bd8a58b7f..74903a8f24 100644 --- a/src/backend/catalog/pg_inherits.c +++ b/src/backend/catalog/pg_inherits.c @@ -242,6 +242,40 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents) } +/* + * get_superclasses - + * Returns a list of relation OIDs of direct parents + */ +List * +get_superclasses(Oid relationId) +{ + List *list = NIL; + Relation catalog; + SysScanDesc scan; + ScanKeyData skey; + HeapTuple inheritsTuple; + Oid inhparent; + + catalog = heap_open(InheritsRelationId, AccessShareLock); + ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, + F_OIDEQ, ObjectIdGetDatum(relationId)); + scan = systable_beginscan(catalog, InheritsRelidSeqnoIndexId, true, + NULL, 1, &skey); + + while ((inheritsTuple = systable_getnext(scan)) != NULL) + { + inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent; + list = lappend_oid(list, inhparent); + } + + systable_endscan(scan); + + heap_close(catalog, AccessShareLock); + + return list; +} + + /* * has_subclass - does this relation have any children? * diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d979ce266d..c76fc3715d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5683,6 +5683,8 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) Relation attr_rel; List *indexoidlist; ListCell *indexoidscan; + List *parentlist; + ListCell *parentscan; ObjectAddress address; /* @@ -5773,6 +5775,24 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) heap_close(parent, AccessShareLock); } + /* If rel has parents, shoudn't drop NOT NULL if parent has the same */ + parentlist = get_superclasses(RelationGetRelid(rel)); + foreach(parentscan, parentlist) { + Oid parentId = lfirst_oid(parentscan); + Relation parent = heap_open(parentId, AccessShareLock); + TupleDesc tupDesc = RelationGetDescr(parent); + AttrNumber parent_attnum; + + parent_attnum = get_attnum(parentId, colName); + if (parent_attnum != InvalidAttrNumber && + TupleDescAttr(tupDesc, parent_attnum - 1)->attnotnull) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("column \"%s\" is marked NOT NULL in parent table", + colName))); + heap_close(parent, AccessShareLock); + } + /* * Okay, actually perform the catalog change ... if needed */ diff --git a/src/include/catalog/pg_inherits_fn.h b/src/include/catalog/pg_inherits_fn.h index 7743388899..291861b846 100644 --- a/src/include/catalog/pg_inherits_fn.h +++ b/src/include/catalog/pg_inherits_fn.h @@ -20,6 +20,7 @@ extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode); extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **parents); +extern List *get_superclasses(Oid relationId); extern bool has_subclass(Oid relationId); extern bool has_superclass(Oid relationId); extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);