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 1wXEMj-0038jm-1m for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jun 2026 08:32:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wXEMh-00A3TT-1v for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jun 2026 08:32:47 +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.96) (envelope-from ) id 1wXEMh-00A3TL-0a for pgsql-hackers@lists.postgresql.org; Wed, 10 Jun 2026 08:32:47 +0000 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wXEMe-00000001ynQ-3ggZ for pgsql-hackers@postgresql.org; Wed, 10 Jun 2026 08:32:45 +0000 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-36babe2c4bdso3967554a91.1 for ; Wed, 10 Jun 2026 01:32:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781080364; cv=none; d=google.com; s=arc-20240605; b=Grs8FcmPZbRWmrrL/HFfdrLTN0bv1L1hXZAL+gtlxQr9hkFT4xVwDu9SWr56FHBicW U5uLwqmPghVH1QQcevTsGXILiMy5tzo5x2pCpG7N0Nqs6kP9FAAhvQRmKbDaWyUsR05v gMWTAfIoLbRiBURMrwfqnylDKozzuiGb/BQswoRgtsq9IiqSpwIEWOYrnsFUO7MJmlNa oqO4ezbEYfm1Wa9DKXRud8NZGGDJCqW1n6WY8YkILcbvGQ2lRxqe0iv2hRHNx/Kb4jrq 3Mmu/824VqYyvU4qfxTEWzWkX4Elh6d81Adgl45Vmdw3N43CsVXTlDiCkHD4DDPMxeD3 GsyQ== 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=BRkQFzmeKLx0bZnjaScAtAQmjGn2vRj9iWDoI1acZXk=; fh=c/W7hNCZjLN+L3G/W6nbCHoildWV8Hk0H9foDtM+dPc=; b=QzO6Sfpoq9faYVH2trH5QXKX6XJ/rBvaLboqz+bBejUw43BiDSAJ6qJs34Y1X6/NQd HCLy6edE2RUOMIaUUSz5LWgB+RQm7k/WuHvwrw+RKe1mQcXQ32LRKFKQ8bKiDKMhJyVb ohMishT7sbR8xxNx7Fp0At9xxOSfd7GWtXD03bocb48jOau0Kt1/0D6XaoVXv8B5RPMT hw22kGl/rpZ8mWp71khd6/e1FqxsnGeNN/tRuawK/DwY91jg9KUPT30bBd0PNZW5GMvY gcXvENM9dfsejsWVN5kv5raFfrRp9CvOBmsLJIP+hq2IAaY7fVFu40/ln56T8TGL/4gR lI7A==; darn=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=1781080364; x=1781685164; darn=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=BRkQFzmeKLx0bZnjaScAtAQmjGn2vRj9iWDoI1acZXk=; b=IgkcvwwrKLarHOj8N+nmQ15kfB2Us0+5A2fuFO1Jx1jMmjtnBWKd7gH3ay+zx2jkl9 NsAkjGa/lEpNcVoZPuhFmbDu4v0AGSY7skSjxZEX17yCOXqbz+KhdqT0ytZFrPoqwC6o Ip6t8E5NksFxMnySqMERFeav6EXYd8QCX33Me5QGTNcK7bsIFoWip1RxQApuyjQrs9cU qJzS+7qL+bJJo3LSidj4o9GcdeT6epBeceeN4MDhmrB9kdHiDpvVrqT7XFabjcp/yfaC f7OWfRrs6b4bK3rKQ5B8rIeHcGCjbtViDuKRfH8IF0vs3hvCxbCf2L7YyOZ1FHDvaL/H jXGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781080364; x=1781685164; 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=BRkQFzmeKLx0bZnjaScAtAQmjGn2vRj9iWDoI1acZXk=; b=Dpc43QZXAmUwAnzEHPlX/axjKkAO8Gleh512dA23+xhUQxKqIYihNPJNW/lW/L2avG SBAmgBjCfzI7fckTdQRY3WVovnx4z3S2PzZtRvDIDJDgc+N+8jI8Gf8dJHaLmIHJwQgH xhJtUjaCw2EXlOcufI82J+kA3MGAQPUKolZZw3VyrWMR6X3P0kFHdAFqH5VuPwyfgYA8 I0dSs97+l4wyh9PZ5m7wQyuw7kYmN+35SU3k9uOtTtEprzCfPZ/vbvxjSecXloTEzCUd o6TxPvNcy1J/oEexPuEI5852aSTBWRJc+zCNTXY6lBshgYsrlByPi7ZS2ispQGn8cCcN Xfsw== X-Gm-Message-State: AOJu0YyPXfpcP5DHhynTzj/HoyIcuQ6NiDkvy0a+7QH+xHfhADuayH3G AbFNbf/mdqddbGWdCbq9/4L3LnB1dCF1q2l5YI2peRRQjrEvzlfvmmjrFvNWpIp/Y8OSDd6Rrkf aHQKCRbdkS78mWEOV4c3u6O1DFmCyFi0= X-Gm-Gg: Acq92OGspNm6ArD58axo5/aupmX9cqT6WCozPtoHceJV41b1NixmYmWXatcQVSPPmV2 aj+d9eOFX012Wvhx5G8u9DTKE/1p9i82rUxuWIz2Jh7wdq9Q2ENLrsAe2pZ0kfJCMChb1WMtiUK v94xodw7MnHcjX+XGaNGgoDhgFVhJtSTv6jzTJXt72HqLYGsvhFNhKz00QGLphqkRHWe8EIOFEu LkI7DiUOE1mUMvzgN1t9WN4bOaDoDiUFYJpr/NJ9JslD9HwHHCvAOKHpfKOSjVN/lbOzwx07Q/U vPwCLPzn5Xnw0pWR8ZJiW5NzEkHMhPPhYRQXYlR4iO5XjkLv0pjS+EnxUoPC0PN/2waKn/htL1U = X-Received: by 2002:a17:90b:3909:b0:36b:bb66:fbd0 with SMTP id 98e67ed59e1d1-370ee33d069mr23559846a91.4.1781080363673; Wed, 10 Jun 2026 01:32:43 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Amit Langote Date: Wed, 10 Jun 2026 17:32:27 +0900 X-Gm-Features: AVVi8CeA-FnU9aFv_Xo_nA4oS15hylPsrtj0Tny8pVH5RQK_Geosb1EnBVLjzEU Message-ID: Subject: Re: PG19 FK fast path: OOB write and missed FK checks during batched To: Nikolay Samokhvalov Cc: pgsql-hackers mailing list , Andrey Borodin , Kirk Wolak 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 Wed, Jun 10, 2026 at 5:16=E2=80=AFPM Nikolay Samokhvalov wrote: > On Tue, Jun 9, 2026 at 6:31=E2=80=AFAM Amit Langote wrote: >> On Mon, Jun 8, 2026 at 5:18=E2=80=AFPM Amit Langote wrote: >> > On Sat, Jun 6, 2026 at 6:13=E2=80=AFPM Amit Langote wrote: >> > > Thanks for the detailed report and reproducers. I=E2=80=99ve started= looking into this. >> > >> > Continuing to look. Appended this to the open items list: >> > >> > https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items#Open_Issues >> >> Thanks again, Nik, for the thorough analysis and the reproducers -- >> they made all three easy to confirm and pin down. Patches attached: >> 0001 for defect 1, 0002 for defects 2 and 3. >> >> 0001 (defect 1): check and flush before writing the row rather than >> after, and add a per-entry "flushing" flag so a re-entrant add on the >> same entry during a flush takes the per-row path instead of touching >> the mid-flush batch. The flag is cleared in a PG_FINALLY, which also >> resets batch_count, so the entry stays reusable if a flush error is >> caught by a savepoint. >> >> 0002 (defects 2 and 3): rather than track subxact membership per row, >> confine batching to the top transaction level -- in RI_FKey_check, >> when GetCurrentTransactionNestLevel() > 1, use the per-row path. I >> went this way because per-entry subxact tracking isn't enough (one >> entry's batch can mix rows from several levels, since the cache is >> keyed by constraint), and flushing at subxact boundaries doesn't work >> for deferred constraints. Once the cache only ever holds top-level >> rows, a subxact abort has nothing of its own to discard, so >> ri_FastPathSubXactCallback goes away -- that's what fixes your defect >> 2 reproducer. For defect 3, which is still reachable at the top level, >> the same patch adds a cache-wide flag set while ri_FastPathEndBatch >> iterates, so a re-entrant check during the scan takes the per-row path >> instead of inserting into the cache being scanned. >> >> The per-row path still bypasses SPI, so these stay well ahead of the >> pre-19 check in terms of performance. I'd like to recover batching >> across subtransactions properly in v20 but didn't want to rush it now. >> >> On defect 3, can you check whether your reproducer still commits the >> orphan with 0002 applied, or whether (like on my build) it now raises >> the violation? I'd like to be sure the bucket-placement variation you >> hit is actually covered. And of course any review of the patches is >> welcome. > > Hi Amit, > > Thanks for the quick fixes. > > I checked v1-0001 + v1-0002 against current master (e18b0cb7) with an ass= ertion/debug build. > > - Both apply cleanly to master (in sequence) > - Defect 1 same-FK re-entry no longer crashes; the original shape complet= es and leaves the expected rows > - Defect 2 subtransaction-abort case now raises the FK violation instead = of committing orphans > - For your defect 3 question: with 0002 applied, my reproducer no longer = commits the child2 orphan. It raises: > ERROR: insert or update on table "child2" violates foreign key constr= aint "child2_fkey" > DETAIL: Key (a)=3D(999999) is not present in table "parent". > > After the error, child2_orphans =3D 0 and child2 is empty in my run. > > I also ran the regression suite in that tree; foreign_key passed, and the= full run reported all 245 tests passed. > > So v1 looks good to me for the three reported cases. Thanks for checking. I will review them a bit more closely before committing by Friday. Other reviews are welcome. --=20 Thanks, Amit Langote