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 1wAHeW-002Ed4-2X for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Apr 2026 01:24:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wAHeV-003hAp-0v for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Apr 2026 01:24:19 +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 1wAHeU-003hAf-2n for pgsql-hackers@lists.postgresql.org; Wed, 08 Apr 2026 01:24:19 +0000 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wAHeT-000000018P2-0zpz for pgsql-hackers@postgresql.org; Wed, 08 Apr 2026 01:24:18 +0000 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-35d9f68d011so3724224a91.2 for ; Tue, 07 Apr 2026 18:24:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775611456; cv=none; d=google.com; s=arc-20240605; b=VBf7+oYGUfKeZKfRz0yuYhIcZ9RdR4kfLCZGihRuA9hqJXaw33KVVlcyZ4QZtzUivT FrTWAFZ1RQPDkS/X1Oj236+RWqAl3cJ19d+S42+SkBiVdl3ZO+WbgPnrEhFKwHze51dQ KL4IJ+YWlsqib5fkHxb/+x5t1LsM1xMUYYtmSuv7Rb3OpKUUZHpIIJ5HgaXAKHQX6XWD yofln3qfx7QX6hQ1SgkazQhJbzZe9aAdatcfSejeOyHUtUYLderXvRqOEjld6C+Va4LZ TWw4hZpj08qltxCy+OaLBlAD9pv3cfmvH2AArsV+y/Ql5VZdZTAkeTLs4XAzJ37Vol2x FApg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=nwkJCKsTqcYQNjmM6fK3VavlVz4s198cJwC5haKjxK4=; fh=Wnw2+2BmbY5bDwDXOiULndM2ZgPQ4yU/F5ezZXkNd9o=; b=BXeQ5TWON/mHr1KV8fBqXx+zL+PtwDWJnWlUpcS8f4D8sb0eHEqiBn01oRKZbGgL7F GzRuY6j2+qR3kSltH/2B76x+G8x0oG1PXP1UduHzvNtInravu63El2k4d974Ru1iIRzL GWZv6Apk1w5IKjXncR+Vl+hUIYXs3D36yXdWaVTzMTvB0gawmxPWOiLjbFH7V1NigPKG oduo3XRbanAVvGaz0jZ+z+/9qWVro8fyaToJeYI75kG5oDxrRwWhHuUbidcIuQPTN24/ J8EKT24KMFVWrfdGtUf4zb1m/tVqyGL4pLnyC2othskFNnXGNrD2l5UuafCs3in1dsua W++w==; 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=1775611456; x=1776216256; darn=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=nwkJCKsTqcYQNjmM6fK3VavlVz4s198cJwC5haKjxK4=; b=RlQ5DTXh4UZcqNmccGtA9RgfP13tEVUQl0hIkhO5y/lP656MGn4iN30uhyjBbIAtHX UTha5SSATMPWXMy//UdLZeBVeL7xeW9WyiIfUnUb7Ffx+ZjaxfRSW95oBs6mhxWkiGQ4 ftRXV+Bf8YgN3v85DPSLFa7BQrx3e3t62Ex1pnabzW13gW+w20ggXLkmaOd1XSPOuQXJ tgJPzdZMVwnsxffSc9dhx7jTvU4ez4rO0pD82qPVWjl8gBUFkpI0fWJVRgMdqxnDOFGb 0+9XbJZlApZw4GfRSKFYI/PDn2A1p4C1qbjkF9YNXNTeJ4G7hnMtuB4S1MblRlgfjO6O K34g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775611456; x=1776216256; h=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=nwkJCKsTqcYQNjmM6fK3VavlVz4s198cJwC5haKjxK4=; b=VAebRohAS8Q+hHitwvUtD5/+1ZYybBbeDqM1XwSVg2agjmfinEHxpAisZvLLLziUA9 pI8YtNjAVrPwxKwwcqYpsKUZhPZFhEVasXnT8b1WGut2Wrm3V0bMje9dciLdEZXpHgiw 7RdeZ2a+Ai4P+sJiNNWdFylvrJ/r4CAJ+HRleHfoXJ79jY/+8OGvlZLfhdYRd8Pjxx4p LaKz8StPhe7JYWM/Iyi3EsjuyGNaYFIz8nvQNKQUcETBsG9Piw37V60SgSdP1EohzdY3 RrFjDsXCNvxfo0GjziRhECWyhVIKY5dRo25gpZ+lkH9l3ko1Lbp2FO4FUcLXvteeYlDE j7Nw== X-Gm-Message-State: AOJu0YzREuF7TvZXNLHM6Y+HiKTxWSWECfohk9Iq/ZmnuvN5a9Uk+XY5 vGPUzIyyyvlfbPN/pZFsyEuTXUWZKXBjuVZlKIR+3J0DJvIHARI3z2kPIDdtV8DZYtZFWHvwJf1 cC+YYw8yheQc9c9WQ4fzEwfREh3pKj1cCxwmv X-Gm-Gg: AeBDieuaMy8wKcvLw9jiZGq/deJDkvqYwFh4I/mf/fl8P7W/t5RWi4w/2i/lxlxCqbF kA5a7fJQlj+Q3BkvHpgJ11a78hvX8nUYSUjgxMSB5af3tmVi8eGmwMKv8sRD5rxoVjqgRbU4eI+ SBqWvyh0saJ6PW0nTZMlSza1FXmiMlPWFfLd7S8nxyzL/FoFPl7xiNkx/1Dd8+SgplB8qhtKXrj JsIP5//UN1F5POKkk1NTqDyzVr/10DMJn3JrA1T42KZqmk5pn5V0TnJ3ROA5v56JDtVDfCSehlI +OpeEJt4 X-Received: by 2002:a17:90b:53cb:b0:341:88d5:a74e with SMTP id 98e67ed59e1d1-35de697374dmr18724570a91.29.1775611456320; Tue, 07 Apr 2026 18:24:16 -0700 (PDT) MIME-Version: 1.0 References: <2BE661BA-D909-4093-BF78-DB9B0C099337@gmail.com> <77FA04FE-1F84-4DA1-8855-8BBFD8CC889A@gmail.com> <72AA2663-B642-4FB1-BDC2-5FAFF2D2DF15@gmail.com> In-Reply-To: From: Amit Langote Date: Wed, 8 Apr 2026 10:23:59 +0900 X-Gm-Features: AQROBzBAS-kcj6Glajhhb50T6QKsPrg5P0-Y3W4LVCjCSU1HwgG7Xn27Rc3oLQo Message-ID: Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3 To: Evan Montgomery-Recht Cc: PostgreSQL-development Content-Type: multipart/mixed; boundary="0000000000001d0c20064ee8c274" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000001d0c20064ee8c274 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Evan, On Tue, Apr 7, 2026 at 10:00=E2=80=AFPM Evan Montgomery-Recht wrote: > > Hi Amit, > > First time contributing to this project, let me know if I missed > something or need to adjust what I put together. > > I found a crash in the RI fast-path FK check code introduced by > 2da86c1ef9b and extended by b7b27eb41a5. C-language extensions that > use SPI to INSERT into tables with multiple FK constraints hit an > assertion failure (or, without assertions, a server crash) when the > batch callback fires. I discovered this via PostGIS's topology CI -- > toTopoGeom() uses SPI to insert into edge_data, which has 4 immediate > FK constraints referencing node and face. PG 18 passes the same test; > the master crashes. > > This appears to be a separate issue from Chao Li's deferred-trigger > batching bug; the patches touch different files and don't conflict. I > did do a regression test on the merge referenced both PostgreSQL and > PostGIS (to validate that this works.) > > The problem: ri_FastPathGetEntry() opens pk_rel/idx_rel and creates > TupleTableSlots, registering them with the current resource owner -- > the SPI portal's. The batch callback ri_FastPathTeardown() only fires > when query_depth =3D=3D 0 (via FireAfterTriggerBatchCallbacks), but by > that time the inner portal has finished and its resource owner has > released the relation references and TupleDesc pins. The teardown then > tries to close relations whose refcounts are already zero: > > TRAP: failed Assert("rel->rd_refcnt > 0"), File: "relcache.c" > > RelationDecrementReferenceCount > -> RelationClose -> index_close -> ri_FastPathTeardown > -> ri_FastPathEndBatch -> FireAfterTriggerBatchCallbacks > -> AfterTriggerEndQuery -> standard_ExecutorFinish > > and TupleDesc pins that are no longer tracked by any resource owner > cause "tupdesc reference not owned by resource owner" errors. > > Note that simple PL/pgSQL functions don't trigger this because > PL/pgSQL's SPI connection spans the entire function call, so the > portal's resource owner outlives the batch callback. The crash > requires nested SPI from a C extension, which creates a shorter-lived > portal. > > The attached patch (against master, for application) fixes this by > transferring both relation references and TupleDesc pins from the > current resource owner to CurTransactionResourceOwner immediately > after creating them in ri_FastPathGetEntry(). The transfer uses > RelationIncrementReferenceCount / PinTupleDesc under the target owner > followed by RelationDecrementReferenceCount / ReleaseTupleDesc under > the original. I chose this over switching CurrentResourceOwner around > the table_open/index_open calls because the latter also affects > transient buffer pins acquired during catalog lookups inside those > functions. > > ri_FastPathTeardown is updated to clear any buffered tuples (whose > buffer pins belong to the current resource owner) before switching to > CurTransactionResourceOwner for the close/drop operations. > > The patch also adds a test module (test_spi_func) with a C function > that executes SQL via SPI_connect/SPI_execute/SPI_finish, since this > crash cannot be triggered from PL/pgSQL. The test exercises the > C-level SPI INSERT with multiple FK constraints, FK violations, and > nested PL/pgSQL-calls-C-SPI (matching the PostGIS call pattern). > > This is purely a correctness fix with no performance or backward > compatibility impact. No documentation changes are needed since this > is an internal bug fix. > > The patch compiles cleanly and passes pgindent, clang-tidy, and > cppcheck. All 247 regression subtests pass, along with the full meson > test suite (370 ok, 0 fail, 21 skipped) (skipped due to hardware > availability on my side this week). I also verified the PostGIS > topology test (toTopoGeom) passes clean with no warnings, and tested > abort paths (FK violation, transaction rollback, subtransaction abort > via EXCEPTION blocks) (not in scope of PostgreSQL but more for my own > verification that things work). Code coverage on the new lines is > 100%. Tested on macOS (aarch64) and Linux (aarch64, via Docker). Thanks for the report and the patch. I'll need to study this one a bit more closely. Added an open item for the time being: https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items > Unrelated to my patch, SonarCloud flagged a potential issue in > recheck_matched_pk_tuple() (line 3370): the function loops over > ii_NumIndexKeyAttrs elements of the skeys array, but the caller in > ri_FastPathFlushArray passes recheck_skey[1] -- an array of exactly > one element. This is safe because ri_FastPathFlushArray is the > > single-column FK path, so ii_NumIndexKeyAttrs is always 1 there. > However, the function signature doesn't communicate this constraint, > which flags as CWE-125 (out-of-bounds read) / CERT C ARR30-C. Adding > an nkeys parameter (like ri_FastPathProbeOne already has) would make > the contract explicit. Makes sense. Will push the attached patch for this. --=20 Thanks, Amit Langote --0000000000001d0c20064ee8c274 Content-Type: application/octet-stream; name="v1-0001-Add-nkeys-parameter-to-recheck_matched_pk_tuple.patch" Content-Disposition: attachment; filename="v1-0001-Add-nkeys-parameter-to-recheck_matched_pk_tuple.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnpd6rfv0 RnJvbSAzNDRiYTY5NDQ1MWZiYWE1N2JiYjJlMTI5MzBmZTIwZmQ0MjVlODA2IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBBbWl0IExhbmdvdGUgPGFtaXRsYW5AcG9zdGdyZXNxbC5vcmc+ CkRhdGU6IFdlZCwgOCBBcHIgMjAyNiAxMDoyMDoxNSArMDkwMApTdWJqZWN0OiBbUEFUQ0ggdjFd IEFkZCBua2V5cyBwYXJhbWV0ZXIgdG8gcmVjaGVja19tYXRjaGVkX3BrX3R1cGxlKCkKClRoZSBm dW5jdGlvbiBsb29wZWQgb3ZlciBpaV9OdW1JbmRleEtleUF0dHJzIGVsZW1lbnRzIG9mIHRoZSBz a2V5cwphcnJheSwgYnV0IG9uZSBjYWxsZXIgKHJpX0Zhc3RQYXRoRmx1c2hBcnJheSkgcGFzc2Vz IGEgb25lLWVsZW1lbnQKYXJyYXkgc2luY2UgaXQgb25seSBoYW5kbGVzIHNpbmdsZS1jb2x1bW4g RktzLiAgVGhlIGZ1bmN0aW9uCnNpZ25hdHVyZSBkaWQgbm90IGNvbW11bmljYXRlIHRoaXMgY29u c3RyYWludCwgd2hpY2ggc3RhdGljIGFuYWx5c2lzCmZsYWdzIGFzIGEgcG90ZW50aWFsIG91dC1v Zi1ib3VuZHMgcmVhZC4KCkFkZCBhbiBua2V5cyBwYXJhbWV0ZXIgYW5kIGFzc2VydCB0aGF0IGl0 IG1hdGNoZXMKaWlfTnVtSW5kZXhLZXlBdHRycywgdGhlbiB1c2UgaXQgaW4gdGhlIGxvb3AuICBU aGUgY2FsbCBzaXRlcwphbHJlYWR5IGtub3cgdGhlIGtleSBjb3VudC4KClJlcG9ydGVkLWJ5OiBF dmFuIE1vbnRnb21lcnktUmVjaHQgPG1vbnRnZUBtaWFuZXR3b3Jrcy5uZXQ+CkRpc2N1c3Npb246 IGh0dHBzOi8vcG9zdGdyLmVzL20vQ0FFZzdwd2NLZjAxRm1EcUZBZi1IenVfcFluTVlTY1lfT3Rp ZC1wZTl1dzNCSjZncTlnQG1haWwuZ21haWwuY29tCi0tLQogc3JjL2JhY2tlbmQvdXRpbHMvYWR0 L3JpX3RyaWdnZXJzLmMgfCAxMSArKysrKystLS0tLQogMSBmaWxlIGNoYW5nZWQsIDYgaW5zZXJ0 aW9ucygrKSwgNSBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC91dGlscy9h ZHQvcmlfdHJpZ2dlcnMuYyBiL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9yaV90cmlnZ2Vycy5jCmlu ZGV4IDg0ZjlmZWNkYjRjLi4xOGVjODU4MzU3ZCAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvdXRp bHMvYWR0L3JpX3RyaWdnZXJzLmMKKysrIGIvc3JjL2JhY2tlbmQvdXRpbHMvYWR0L3JpX3RyaWdn ZXJzLmMKQEAgLTMyOSw3ICszMjksNyBAQCBzdGF0aWMgYm9vbCByaV9Mb2NrUEtUdXBsZShSZWxh dGlvbiBwa19yZWwsIFR1cGxlVGFibGVTbG90ICpzbG90LCBTbmFwc2hvdCBzbmFwLAogc3RhdGlj IGJvb2wgcmlfZmFzdHBhdGhfaXNfYXBwbGljYWJsZShjb25zdCBSSV9Db25zdHJhaW50SW5mbyAq cmlpbmZvKTsKIHN0YXRpYyB2b2lkIHJpX0NoZWNrUGVybWlzc2lvbnMoUmVsYXRpb24gcXVlcnlf cmVsKTsKIHN0YXRpYyBib29sIHJlY2hlY2tfbWF0Y2hlZF9wa190dXBsZShSZWxhdGlvbiBpZHhy ZWwsIFNjYW5LZXlEYXRhICpza2V5cywKLQkJCQkJCQkJCSBUdXBsZVRhYmxlU2xvdCAqbmV3X3Ns b3QpOworCQkJCQkJCQkJIGludCBua2V5cywgVHVwbGVUYWJsZVNsb3QgKm5ld19zbG90KTsKIHN0 YXRpYyB2b2lkIGJ1aWxkX2luZGV4X3NjYW5rZXlzKGNvbnN0IFJJX0NvbnN0cmFpbnRJbmZvICpy aWluZm8sCiAJCQkJCQkJCSBSZWxhdGlvbiBpZHhfcmVsLCBEYXR1bSAqcGtfdmFscywKIAkJCQkJ CQkJIGNoYXIgKnBrX251bGxzLCBTY2FuS2V5IHNrZXlzKTsKQEAgLTMxMzgsNyArMzEzOCw3IEBA IHJpX0Zhc3RQYXRoRmx1c2hBcnJheShSSV9GYXN0UGF0aEVudHJ5ICpmcGVudHJ5LCBUdXBsZVRh YmxlU2xvdCAqZmtfc2xvdCwKIAkJCQkJCQkJICAgaWR4X3JlbC0+cmRfaW5kY29sbGF0aW9uWzBd LAogCQkJCQkJCQkgICBmcG1ldGEtPnJlZ29wc1swXSwKIAkJCQkJCQkJICAgZm91bmRfdmFsKTsK LQkJCWlmICghcmVjaGVja19tYXRjaGVkX3BrX3R1cGxlKGlkeF9yZWwsIHJlY2hlY2tfc2tleSwg cGtfc2xvdCkpCisJCQlpZiAoIXJlY2hlY2tfbWF0Y2hlZF9wa190dXBsZShpZHhfcmVsLCByZWNo ZWNrX3NrZXksIDEsIHBrX3Nsb3QpKQogCQkJCWNvbnRpbnVlOwogCQl9CiAKQEAgLTMxOTMsNyAr MzE5Myw3IEBAIHJpX0Zhc3RQYXRoUHJvYmVPbmUoUmVsYXRpb24gcGtfcmVsLCBSZWxhdGlvbiBp ZHhfcmVsLAogCQkJCQkJICAgJmNvbmN1cnJlbnRseV91cGRhdGVkKSkKIAkJewogCQkJaWYgKGNv bmN1cnJlbnRseV91cGRhdGVkKQotCQkJCWZvdW5kID0gcmVjaGVja19tYXRjaGVkX3BrX3R1cGxl KGlkeF9yZWwsIHNrZXksIHNsb3QpOworCQkJCWZvdW5kID0gcmVjaGVja19tYXRjaGVkX3BrX3R1 cGxlKGlkeF9yZWwsIHNrZXksIG5rZXlzLCBzbG90KTsKIAkJCWVsc2UKIAkJCQlmb3VuZCA9IHRy dWU7CiAJCX0KQEAgLTMzNDAsNyArMzM0MCw3IEBAIHJpX0NoZWNrUGVybWlzc2lvbnMoUmVsYXRp b24gcXVlcnlfcmVsKQogICogbm90IGZvdW5kLgogICovCiBzdGF0aWMgYm9vbAotcmVjaGVja19t YXRjaGVkX3BrX3R1cGxlKFJlbGF0aW9uIGlkeHJlbCwgU2NhbktleURhdGEgKnNrZXlzLAorcmVj aGVja19tYXRjaGVkX3BrX3R1cGxlKFJlbGF0aW9uIGlkeHJlbCwgU2NhbktleURhdGEgKnNrZXlz LCBpbnQgbmtleXMsCiAJCQkJCQkgVHVwbGVUYWJsZVNsb3QgKm5ld19zbG90KQogewogCS8qCkBA IC0zMzU5LDggKzMzNTksOSBAQCByZWNoZWNrX21hdGNoZWRfcGtfdHVwbGUoUmVsYXRpb24gaWR4 cmVsLCBTY2FuS2V5RGF0YSAqc2tleXMsCiAJCSAgIGluZGV4SW5mby0+aWlfRXhjbHVzaW9uT3Bz ID09IE5VTEwpOwogCiAJLyogRm9ybSB0aGUgaW5kZXggdmFsdWVzIGFuZCBpc251bGwgZmxhZ3Mg Z2l2ZW4gdGhlIHRhYmxlIHR1cGxlLiAqLworCUFzc2VydChua2V5cyA9PSBpbmRleEluZm8tPmlp X051bUluZGV4S2V5QXR0cnMpOwogCUZvcm1JbmRleERhdHVtKGluZGV4SW5mbywgbmV3X3Nsb3Qs IE5VTEwsIHZhbHVlcywgaXNudWxsKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IGluZGV4SW5mby0+ aWlfTnVtSW5kZXhLZXlBdHRyczsgaSsrKQorCWZvciAoaW50IGkgPSAwOyBpIDwgbmtleXM7IGkr KykKIAl7CiAJCVNjYW5LZXlEYXRhICpza2V5ID0gJnNrZXlzW2ldOwogCi0tIAoyLjQ3LjMKCg== --0000000000001d0c20064ee8c274--