Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wRkvI-002f1Z-35 for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 06:05:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wRkvG-003MD1-32 for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 06:05:51 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wRkvG-003MCr-25 for pgsql-hackers@lists.postgresql.org; Tue, 26 May 2026 06:05:51 +0000 Received: from mail-vs1-xe29.google.com ([2607:f8b0:4864:20::e29]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wRkvF-00000001TJu-22QP for pgsql-hackers@lists.postgresql.org; Tue, 26 May 2026 06:05:51 +0000 Received: by mail-vs1-xe29.google.com with SMTP id ada2fe7eead31-63124a80693so3854310137.3 for ; Mon, 25 May 2026 23:05:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779775547; cv=none; d=google.com; s=arc-20240605; b=alTYcueK3nNpLbeY6q21FiGVrhVTylL8iBjXE7+6CZtwVnkeEod73ZtPtaofgKOPzR AN5RS1CJWLeN+bgdjS/FaovJ9piznLXzN18A78i6amuqVhEV9QvNl7phbGxI+f7fihwP rsHt3E62A/7hjjbVLEv/p0XNsXhfK1xLkoNn2zgNjc2PaH+2hx1n9+RQS7D5vaWt6hhE S/k1Vvj+lJ3Pu6M1arRvDUAsenpXWAzx12VNdO8kEl2+E6WT6tuva5SXXS1sO1nA/8pw z+CVgBqTbXkyRBgNr51aVFqwDcNWsqBfDcUn7+CH90g92u2phzDXgi3sQqCWLhmAb1Tx zHow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=Yf06PK4IU0mQ2I9E77ttkfLPT4nKDp9mN1b4E9iI1IA=; fh=nwe3Dj5ygolw4Uxx1iw69hHB5/+QGrYbYAzb2ol+yjs=; b=ad4kEKE2b35SUGe3zaruT5wA42/IxruJYTsxQlDoaZue1Y8lDZ0TEYu5f7bxkAeJPH GvIDeGukDsh8Y3FvPNTNpjb9JTUHAW80dhbHZ+XsF98zEUmvOPX9VRWTH/AsExIxuSVK r/QEyy/jajsnPsxpSAGdY4mn09pVnFkt1XSDcB6J0mAVrPh0PpQd1B28ky2fuN5dcYav OG1yatBn3N1PHnpwq9bP73yshA/mYS7DuqTArmdv5mdFqPZnfZSDsI2dDyhjCaZhgC+1 ki/pt33bR3/um2I6nRCxQQn3TY09A+yGT2pz8ozzSvdxsW66+4r5pMiDEpU3XW5OWWZB vzqg==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779775547; x=1780380347; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=Yf06PK4IU0mQ2I9E77ttkfLPT4nKDp9mN1b4E9iI1IA=; b=kWU+RI6skd+tdwZ1JlJwC2wZ0WmOiR0CLyQfivXiAVwqQ25mOQFEzTR1CUzWEm8anG 0/31uFpnQJGyzpE/yGQlTqSvGVIjq3Z4UQYbXFLPH9569WPC9daRSEQ84jafRIz7nZ0J VEFgMbduvepb3fmzOsSJwLMQEqFt0Kb6j4Lt1uUudHOpZI56h5Ecuv9Ejk6T8/8XiM5R 9MvVDuV8etyGRtNsaG6W1zKDk69tVVBw1BWFWLcGbkj13FkX9Hxc/hCTsv6yg8YijG35 Tp33KT1YieP9jfVK++VGp+0KUPLyPZEAvDuMTbYNMWhV8SgBsJtNDfrlxLjAOB3uAKIz qRRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779775547; x=1780380347; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Yf06PK4IU0mQ2I9E77ttkfLPT4nKDp9mN1b4E9iI1IA=; b=Aa2bMOZcVKhkrNb4ON/QLwVlui9sEvjj4PW4XhjjLs41q8hfeGZOt5NM3P8PRp5bzD o0AC8yzOoM5ohscEDt3qbOPXjfQi0t3Ir34QeVlGVbLj7D41RZW9HJXdl/zptH9V3zMs xzjVHW2CJth6rkywZN/4/XjvMkv1rTMz0Y8BdtEDk13pw7waDVlGRxA/mi7JWglpdq6p k483TkmrR6MWWavRAVB6Hsu9Aul1fVRUinEqG4mjXyLphSUhbWY483XEmUpzxxK1Kg4B nijgSivAlPzownBtlTBRZQqa3lPo8VK3InfF4ht9C9//iMzB6Yx+zCE+FnhWktQ6py8c SdiQ== X-Gm-Message-State: AOJu0YxNyJrMFGLRq91FF2iSwfmEve1T+sTa0IrXeJ8KQhjyBfUpsOoJ yNWYxc1MDYzLnlFxdpGd8g83A9H40U48sH3tL7qQMCEGpHjEW+EAZLWp6jmJn9zXqjJqPsRKZon 8BQTYLiBxp/8+++sdOhw6t5pF9ZZfHWw= X-Gm-Gg: Acq92OHjk2ntdWP5rvX3ybat8jmxo3xi5PO1XRRItKqhn123khWyozbOwK9kxxTK+xw Xzebojp3mrlREJkyRwYrLdPQ2BPc6d8KJ+HDThUqc1FV/IvOc+6KFVse1IhCsRvUVCqhKK+09z3 tlEG+hdbUmSd3mQz2qaOcGCVdDIcaWLKwNb8dIDvNhv1atkx7Vf+kmTFrRoDU0GpqRL0vVs6rF/ O/weX9uR0rbe5cvhbEYe1tQ9aXNiAChIGqbDBL9gRPYp7rai1qYS8v3e4mBAlyyaOfc8d2o5yhK 8fu15Eue6ohYRZxhlC3Lr/s2sMXx5yezn/QZcdMceXlxq1+cKaVPAjvhyTIhmJun8Hcl8F54URg k+eMwbCw7VlXntWEcxv8VUY6hWRalR2eIIOrf/F91WZnkoHtII0koENkCRnr6ZshnDeqsTbgVbT lkptZ62KudKuCI8NRPGbToeMAKKzCFX6TI X-Received: by 2002:a05:6102:fa5:b0:633:bc46:c20a with SMTP id ada2fe7eead31-67c84adf950mr8259636137.31.1779775547238; Mon, 25 May 2026 23:05:47 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: jian he Date: Tue, 26 May 2026 14:05:08 +0800 X-Gm-Features: AVHnY4JAQomYkdl0nlr4Vb2JsTa87ei_JKLTSMI0ynsPgiX3A0qsNus1ExXyMy8 Message-ID: Subject: Re: Fix bug of CHECK constraint enforceability recursion To: Chao Li Cc: PostgreSQL Hackers , Andrew Dunstan Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, May 26, 2026 at 11:51=E2=80=AFAM Chao Li w= rote: > > Hi, > > I just tested =E2=80=9CAdd support for altering CHECK constraint enforcea= bility=E2=80=9D and found an issue where recursion is not handled properly. > > Here is a repro with inheritance tables: > ``` > evantest=3D# create table p(a int constraint ck check (a > 0) enforced); > CREATE TABLE > evantest=3D# create table c() inherits (p); > CREATE TABLE > evantest=3D# alter table c alter constraint ck not enforced; > ALTER TABLE > evantest=3D# insert into c values (-1); > INSERT 0 1 > evantest=3D# alter table p alter constraint ck enforced; > ALTER TABLE > evantest=3D# insert into c values (-2); > INSERT 0 1 > evantest=3D# select * from p; > a > ---- > -1 > -2 > (2 rows) > ``` > > In this repro, the constraint on parent table p is already ENFORCED, but = the constraint on child table c was altered to NOT ENFORCED. So when alteri= ng p to ENFORCED again, it didn't recurse to c. > > The same problem can happen with partitioned tables as well: > ``` Hi. In MergeConstraintsIntoExisting, we have: /* * A NOT ENFORCED child constraint cannot be merged with an * ENFORCED parent constraint. However, the reverse is allowed, * where the child constraint is ENFORCED. */ if (parent_con->conenforced && !child_con->conenforced) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("constraint \"%s\" conflicts with NOT ENFORCED constraint on child table \"%s\"", NameStr(child_con->conname), RelationGetRelationName(child_rel)))); MergeWithExistingConstraint, we have comments like: /* * If the child constraint is required to be enforced while the par= ent * constraint is not, this should be allowed by marking the child * constraint as enforced. In the reverse case, an error would have * already been thrown before reaching this point. */ So other commands (CREATE TABLE, ALTER TABLE ATTACH PARTITION) do not expec= t a state where the parent constraint is enforced but the child constraint is n= ot. We can now reach this state via ALTER TABLE ALTER CONSTRAINT. We don't need to worry about Foreign Key Constraints because the foreign key constraint's conparentid is valid, therefore we cannot directly alter a partition's FK constraint. StoreRelCheck->CreateConstraintEntry comments ``/* no parent constraint */`` means that each CHECK constraint is on its own. Overall, i tend to think that we should reject ALTER TABLE ALTER CONSTRAINT if it would result in the parent constraint being enforced while the child constr= aint is not enforced. -- jian https://www.enterprisedb.com/