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.94.2) (envelope-from ) id 1sTdZ3-000mCr-La for pgsql-hackers@arkaria.postgresql.org; Tue, 16 Jul 2024 08:29:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sTdZ2-00GYEw-Bm for pgsql-hackers@arkaria.postgresql.org; Tue, 16 Jul 2024 08:29:36 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sTdZ1-00GYEO-LZ for pgsql-hackers@lists.postgresql.org; Tue, 16 Jul 2024 08:29:35 +0000 Received: from mail-vk1-xa2e.google.com ([2607:f8b0:4864:20::a2e]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sTdYz-002JKN-3u for pgsql-hackers@lists.postgresql.org; Tue, 16 Jul 2024 08:29:34 +0000 Received: by mail-vk1-xa2e.google.com with SMTP id 71dfb90a1353d-4f2e13622e4so1881154e0c.3 for ; Tue, 16 Jul 2024 01:29:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1721118572; x=1721723372; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=eRWQryNFsvDwwIw9oe2Bo/NWU3/MFqqJ/wRVSAYZj7k=; b=PPeQVbaUm4RJAQsJHZPT9UJWa8scbT1++37S+t1dBQ5e/gUubggF4K6inPaQ1B6OT7 D/b7wZl2BEypwosspvB5pByIgw+H64/kyBVixwjyngGO9GcllV6vX+RbvOToiNV0h6hy l0iTQhwT0hUPQ7D0IEIVFmTcO7miEPwQrFOIuEq/TYc5ptkvl/Tb4BD0a/AZDzpO1hnh EJG6mUozqPFaGppierWybvgVwGd40Puk1XdiQGm//uUTPKL+JC6ZDa54WvYIwTewLrF5 M6FiDAcFI9xuykVJMfVleWoSSxxqrxvk0QqjYRyg1eTggEdM0OxU8abXrCKj+7W/zQUH j33g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721118572; x=1721723372; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=eRWQryNFsvDwwIw9oe2Bo/NWU3/MFqqJ/wRVSAYZj7k=; b=DC7deOUQyqY5u8DLPT2mhrpZvCUQjeXoLhksxP83oU4LPgvM0En/yKNDD9COsIpfGr yepSk6IyTrX5C2LGyFPyJEx9ViM/rI9QTMCYca09U8sWSQFzyVYrKI5JLMINLPM+HDSH uN3tzmNIN2xRYB4hKKWC51aAca1Voi0L6waWf5Bq+rWhxQ39E8uyNh3M+NJBedPLAZX0 0gmhpSSSZwaOSmyc49OE+2bohmlz4MlvapKabHKy+NBblGWtkh60KmK1QmV9lBj3GUk8 90+eJoBy1NWVVEKpDWE5uBhfUpo0iEnfjOUHh4VUrobeGCZrcRimXjbZWRoECgZ8k/L9 OxFA== X-Forwarded-Encrypted: i=1; AJvYcCU51oToqI/3MTOwsgfIAaJcME2WGJ6GkJDQpw8XhY0E5Y5h8VxmekukY+caGpXXeg1NOY+F5yG05LgV/pD/dArDbsv0DBfglc37c3pYNw5/aB5s X-Gm-Message-State: AOJu0YzzMR0H2Ywypu98GYLUaO8MArYq1mmYxWzUXRwnvd+TF/rpXEH4 +Gtn9GCJpKRPhsW3mqQsjQtZDeK264qDKiN30NzuIXF9sbQ+tED9sMJPVGXfFD93wKYF2MtuVLo MXhrDOK3YxeK0MamjwU6L5F+HQeY= X-Google-Smtp-Source: AGHT+IGZql/BWefv+KiR4ZI0AUZiQjRBEPJMK1DHlp/6hL/v52h4b62bK0jrPurf2Bmc2gfMblZMsM8odZmx2cjTPxU= X-Received: by 2002:a05:6122:3107:b0:4f2:f1f1:a9f2 with SMTP id 71dfb90a1353d-4f4d6f1c92emr6803e0c.4.1721118572100; Tue, 16 Jul 2024 01:29:32 -0700 (PDT) MIME-Version: 1.0 References: <78d824e0-b21e-480d-a252-e4b84bc2c24b@illuminatedcomputing.com> <69f0a887-a4ed-49cf-9d63-923891006658@illuminatedcomputing.com> <216627.1717791128@sss.pgh.pa.us> In-Reply-To: From: jian he Date: Tue, 16 Jul 2024 16:29:00 +0800 Message-ID: Subject: Re: altering a column's collation leaves an invalid foreign key To: Peter Eisentraut Cc: Tom Lane , Paul Jungwirth , PostgreSQL Hackers Content-Type: multipart/mixed; boundary="0000000000001b5998061d59257c" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000001b5998061d59257c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Jun 18, 2024 at 4:50=E2=80=AFPM Peter Eisentraut wrote: > > On 08.06.24 06:14, jian he wrote: > > if FK is nondeterministic, then it looks PK more like FK. > > the following example, one FK row is referenced by two PK rows. > > > > DROP TABLE IF EXISTS fktable, pktable; > > CREATE TABLE pktable (x text COLLATE "C" PRIMARY KEY); > > CREATE TABLE fktable (x text COLLATE ignore_accent_case REFERENCES > > pktable on update cascade on delete cascade); > > INSERT INTO pktable VALUES ('A'), ('=C3=85'); > > INSERT INTO fktable VALUES ('A'); > > Yes, this is a problem. The RI checks are done with the collation of > the primary key. > > The comment at ri_GenerateQualCollation() says "the SQL standard > specifies that RI comparisons should use the referenced column's > collation". But this is not what it says in my current copy. > > ... [ digs around ISO archives ] ... > > Yes, this was changed in SQL:2016 to require the collation on the PK > side and the FK side to match at constraint creation time. The argument > made is exactly the same we have here. This was actually already the > rule in SQL:1999 but was then relaxed in SQL:2003 and then changed back > because it was a mistake. > > We probably don't need to enforce this for deterministic collations, > which would preserve some backward compatibility. > > I'll think some more about what steps to take to solve this and what to > do about back branches etc. > I have come up with 3 corner cases. ---case1. not ok. PK indeterministic, FK default DROP TABLE IF EXISTS fktable, pktable; CREATE TABLE pktable (x text COLLATE ignore_accent_case PRIMARY KEY); CREATE TABLE fktable (x text REFERENCES pktable on update cascade on delete cascade); INSERT INTO pktable VALUES ('A'); INSERT INTO fktable VALUES ('a'); INSERT INTO fktable VALUES ('A'); RI_FKey_check (Check foreign key existence ) querybuf.data is SELECT 1 FROM ONLY "public"."pktable" x WHERE "x" OPERATOR(pg_catalog.=3D) $1 FOR KEY SHARE OF x in here, fktable doesn't have collation. we cannot rewrite to SELECT 1 FROM ONLY "public"."pktable" x WHERE "x" OPERATOR(pg_catalog.=3D) $1 collate "C" FOR KEY SHARE OF x so assumption (only one referenced row for any referencing row) will break when inserting values to fktable. RI_FKey_check already allows invalidate values to happen, not sure how ri_GenerateQualCollation can help. overall i don't know how to stop invalid value while inserting value to fktable in this case. ---case2. not ok case PK deterministic, FK indeterministic DROP TABLE IF EXISTS fktable, pktable; CREATE TABLE pktable (x text COLLATE "C" PRIMARY KEY); CREATE TABLE fktable (x text COLLATE ignore_accent_case REFERENCES pktable on update cascade on delete cascade); INSERT INTO pktable VALUES ('A'), ('=C3=85'); INSERT INTO fktable VALUES ('A'); begin; update pktable set x =3D 'B' where x =3D '=C3=85'; table fktable; r= ollback; begin; update pktable set x =3D 'B' where x =3D 'A'; table fktable; rollba= ck; when cascade update fktable, in RI_FKey_cascade_upd we can use pktable's collation. but again, a query updating fktable only, using pktable collation seems strange. ---case3. ---not ok case PK indeterministic, FK deterministic DROP TABLE IF EXISTS fktable, pktable; CREATE TABLE pktable (x text COLLATE ignore_accent_case PRIMARY KEY); CREATE TABLE fktable (x text collate "C" REFERENCES pktable on update cascade on delete cascade); INSERT INTO pktable VALUES ('A'); INSERT INTO fktable VALUES ('A'); INSERT INTO fktable VALUES ('a'); begin; update pktable set x =3D '=C3=85'; table fktable; rollback; when we "INSERT INTO fktable VALUES ('a');" we can disallow this invalid query in RI_FKey_check by constructing the following stop query SELECT 1 FROM ONLY public.pktable x WHERE x OPERATOR(pg_catalog.=3D) 'a' collate "C" FOR KEY SHARE OF x; but this query associated PK table with fktable collation seems weird? summary: case1 seems hard to resolve case2 can be resolved in ri_GenerateQualCollation, not 100% sure. case3 can be resolved in RI_FKey_check because case1 is hard to resolve; so overall I feel like erroring out PK indeterministic and FK indeterministic while creating foreign keys is easier. We can mandate foreign keys and primary key columns be deterministic in ATAddForeignKeyConstraint. The attached patch does that. That means src/test/regress/sql/collate.icu.utf8.sql table test10pk, table test11pk will have a big change. so only attach src/backend/commands/tablecmds.c changes. --0000000000001b5998061d59257c Content-Type: text/x-patch; charset="US-ASCII"; name="make_pk_fk_tie_collation_deterministic.diff" Content-Disposition: attachment; filename="make_pk_fk_tie_collation_deterministic.diff" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lyo56x100 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL2NvbW1hbmRzL3RhYmxlY21kcy5jIGIvc3JjL2JhY2tl bmQvY29tbWFuZHMvdGFibGVjbWRzLmMKaW5kZXggNzIxZDI0NzguLjQ5MWJhODdjIDEwMDY0NAot LS0gYS9zcmMvYmFja2VuZC9jb21tYW5kcy90YWJsZWNtZHMuYworKysgYi9zcmMvYmFja2VuZC9j b21tYW5kcy90YWJsZWNtZHMuYwpAQCAtOTc1Nyw2ICs5NzU3LDM5IEBAIEFUQWRkRm9yZWlnbktl eUNvbnN0cmFpbnQoTGlzdCAqKndxdWV1ZSwgQWx0ZXJlZFRhYmxlSW5mbyAqdGFiLCBSZWxhdGlv biByZWwsCiAJCQkJKGVycmNvZGUoRVJSQ09ERV9JTlZBTElEX0ZPUkVJR05fS0VZKSwKIAkJCQkg ZXJybXNnKCJudW1iZXIgb2YgcmVmZXJlbmNpbmcgYW5kIHJlZmVyZW5jZWQgY29sdW1ucyBmb3Ig Zm9yZWlnbiBrZXkgZGlzYWdyZWUiKSkpOwogCisJZm9yIChpID0gMDsgaSA8IG51bXBrczsgaSsr KQorCXsKKwkJaW50MzIJCWtleWNvbHR5cG1vZDsKKwkJT2lkCQkJa2V5Y29sdHlwZTsKKwkJT2lk CQkJa2V5Y29sY29sbGF0aW9uOworCisJCWdldF9hdHR0eXBldHlwbW9kY29sbChSZWxhdGlvbkdl dFJlbGlkKHBrcmVsKSwgcGthdHRudW1baV0sCisJCQkJCQkJCSZrZXljb2x0eXBlLCAma2V5Y29s dHlwbW9kLAorCQkJCQkJCQkma2V5Y29sY29sbGF0aW9uKTsKKwkJaWYgKE9pZElzVmFsaWQoa2V5 Y29sY29sbGF0aW9uKSAmJgorCQkJCSFnZXRfY29sbGF0aW9uX2lzZGV0ZXJtaW5pc3RpYyhrZXlj b2xjb2xsYXRpb24pKQorCQkJZXJlcG9ydChFUlJPUiwKKwkJCQkJKGVycmNvZGUoRVJSQ09ERV9E QVRBVFlQRV9NSVNNQVRDSCksCisJCQkJCQkgZXJybXNnKCJmb3JlaWduIGtleSBjb25zdHJhaW50 IFwiJXNcIiBjYW5ub3QgYmUgaW1wbGVtZW50ZWQiLAorCQkJCQkJCQlma2NvbnN0cmFpbnQtPmNv bm5hbWUpLAorCQkJCQkJIGVycmRldGFpbCgiQ2Fubm90IGhhdmUgaW5kZXRlcm1pbmlzdGljIGNv bGxhdGlvbnMgaW4gcHJpbWFyeSBrZXkgZm9yIHJlZmVyZW5jZWQgdGFibGUgXCIlc1wiIiwKKwkJ CQkJCQkJUmVsYXRpb25HZXRSZWxhdGlvbk5hbWUocGtyZWwpKSwKKwkJCQkJCSBlcnJoaW50KCJZ b3UgbWF5IG1ha2UgdGhlIHByaW1hcnkga2V5IGNvbGxhdGlvbnMgZGV0ZXJtaW5pc3RpYy4iKSkp OworCisJCWdldF9hdHR0eXBldHlwbW9kY29sbChSZWxhdGlvbkdldFJlbGlkKHJlbCksIGZrYXR0 bnVtW2ldLAorCQkJCQkJCQkma2V5Y29sdHlwZSwgJmtleWNvbHR5cG1vZCwKKwkJCQkJCQkJJmtl eWNvbGNvbGxhdGlvbik7CisJCWlmIChPaWRJc1ZhbGlkKGtleWNvbGNvbGxhdGlvbikgJiYKKwkJ CQkhZ2V0X2NvbGxhdGlvbl9pc2RldGVybWluaXN0aWMoa2V5Y29sY29sbGF0aW9uKSkKKwkJCWVy ZXBvcnQoRVJST1IsCisJCQkJCShlcnJjb2RlKEVSUkNPREVfREFUQVRZUEVfTUlTTUFUQ0gpLAor CQkJCQkgZXJybXNnKCJmb3JlaWduIGtleSBjb25zdHJhaW50IFwiJXNcIiBjYW5ub3QgYmUgaW1w bGVtZW50ZWQiLAorCQkJCQkJCWZrY29uc3RyYWludC0+Y29ubmFtZSksCisJCQkJCSBlcnJkZXRh aWwoIkZvcmVpZ24ga2V5IGNhbm5vdCB1c2UgaW5kZXRlcm1pbmlzdGljIGNvbGxhdGlvbnMgZm9y IHJlZmVyZW5jaW5nIHRhYmxlIFwiJXNcIiIsCisJCQkJCQlSZWxhdGlvbkdldFJlbGF0aW9uTmFt ZShyZWwpKSwKKwkJCQkJIGVycmhpbnQoIllvdSBtYXkgbWFrZSB0aGUgZm9yZWlnbiBrZXkgY29s bGF0aW9ucyBkZXRlcm1pbmlzdGljLiIpKSk7CisJfQorCiAJLyoKIAkgKiBPbiB0aGUgc3RyZW5n dGggb2YgYSBwcmV2aW91cyBjb25zdHJhaW50LCB3ZSBtaWdodCBhdm9pZCBzY2FubmluZwogCSAq IHRhYmxlcyB0byB2YWxpZGF0ZSB0aGlzIG9uZS4gIFNlZSBiZWxvdy4K --0000000000001b5998061d59257c--