special_case_CHECK_parent.patch
text/x-patch
Filename: special_case_CHECK_parent.patch
Type: text/x-patch
Part: 0
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 82bb756..5340402 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5433,6 +5433,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
ListCell *lcon;
List *children;
ListCell *child;
+ bool skip_children = false;
/* At top level, permission check was done in ATPrepCmd, else do it */
if (recursing)
@@ -5502,9 +5503,31 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
* tables; else the addition would put them out of step.
*/
if (children && !recurse)
- ereport(ERROR,
+ {
+ /*
+ * Try a bit harder and check if this is a CHECK(FALSE) kinda
+ * constraint. Allow if so, otherwise error out
+ */
+ if (list_length(newcons) == 1)
+ {
+ CookedConstraint *cooked = linitial(newcons);
+
+ if (cooked->contype == CONSTR_CHECK && cooked->expr)
+ {
+ Node *expr = cooked->expr;
+ if (IsA(expr, Const) && ((Const *)expr)->consttype == BOOLOID &&
+ ((Const *)expr)->constvalue == 0)
+ {
+ skip_children = true;
+ }
+ }
+ }
+
+ if (!skip_children)
+ ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("constraint must be added to child tables too")));
+ }
foreach(child, children)
{
@@ -5512,6 +5535,13 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
Relation childrel;
AlteredTableInfo *childtab;
+ /*
+ * Skipping the constraint should be good enough for the special case.
+ * No need to even release the locks on the children immediately..
+ */
+ if (skip_children)
+ break;
+
/* find_inheritance_children already got lock */
childrel = heap_open(childrelid, NoLock);
CheckTableNotInUse(childrel, "ALTER TABLE");