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 1vBZKA-000fgx-4O for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Oct 2025 13:56:21 +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 1vBZK8-00Gjwy-4O for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Oct 2025 13:56:19 +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.94.2) (envelope-from ) id 1vBZK7-00Gjwc-Pq for pgsql-hackers@lists.postgresql.org; Wed, 22 Oct 2025 13:56:18 +0000 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vBZK1-003csh-1o for pgsql-hackers@postgresql.org; Wed, 22 Oct 2025 13:56:18 +0000 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-33bda2306c5so5573445a91.0 for ; Wed, 22 Oct 2025 06:56:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761141371; x=1761746171; 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=htFKknTDqMzqRa+uRFRKiifSqRmXbrwbLJYhPa/2dlE=; b=WIp40o8ojjAg1J5o1V0P80CbfAWgNdZUMBUjzmAX0FSNkwSZ3UIVcWWNFXLyQp5SCd Ufkl32yFXsByqZO72s0jWSbw2MyF232Aqy48xEIyskpZGnXxJEq1iQoAQdmDHCzGxYb7 USQQP+iO5N1vSbTSjEQH1jeSgyCZhujBYR0WaiYGatVDkm6kAc5YaXs3jEfi2iNT1/uP 8YFkOceb4zLTHM64sNj42u9ygyBHpISj3DOTPqLR+oUruHR6Z5Qi0itAIkM4HnnaPRAn SCMSKP3WPcA1KXaZf/A2W0WxIYzuyde9YHaWNDgr0h2M78bCY5/D0AL4iByXoWTIs9Bo JEvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761141371; x=1761746171; h=content-transfer-encoding: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=htFKknTDqMzqRa+uRFRKiifSqRmXbrwbLJYhPa/2dlE=; b=VX/pMnG1tS0DSrVKvVdFTe5W3KnDMPYzh0D1zko5UB7WHEIZpYO4HhNEVsUldhk+5g ua+Qf5+oFV3I/dA2cV7mtt7CP7o+eqVOt3ORw5Ihi1klPWvdGLVcutGd9fNkLhRN1SdM NHTG01J2OTKc6f2oBFDhIyC5XOtAmvabykwzbHpxlYmix6Xa8V8VNpGb/tsTNJDy/SeX 7PGHT+o++RXCOo4/y4Il2z/WpIM6NwtXDqQz8QtzoemJsP1onzxLS6lfoz1DyEhRpuaV ya5KIaDFajtCcjFDndhjg/K28uItyM0OBNhQNHJXPw0OtFRdhZyt6Mlk5UPx9b7yC1HP svzQ== X-Gm-Message-State: AOJu0YzuVRbYmbiorFYt1mmDT0IAw0PZsgC7lR6FcbpT7xgeXMg6uQjU rbcu2vtUChTT7ooVgj1CzV+5PZF8WJjbW5hSLoMKdE+lRQwOoLYWJbmzn/Sxy14gidSE9Be+ySa J6/eSzmzpDduGheapZQLItCWk6ZSVSkA= X-Gm-Gg: ASbGncuhLq9y5Jx64hVfm6VCe1e4FqFvKVH3tjWX54HvZJCkXOvQwSpVMfVSCMCzuRK 8S1ZcFAD/G7aSfR0p6giyY0Q2SsRB3KHD5EiTSBaGFTSrHOzUjdkjsi0O0ZxkpZcp28QTw8QeiL xIKag10iJ3O7xjsrrUEAH2K5X9OY7tdpvHNzMCenBklfc+UmROV/N9C4Z0Y0Wkh4XQLKXa7xACU 2nl/6Ptnc4WJhk49Tn2joS5HjKcvszmxKg6BH043LLZY9pAavdApsY2PHrB76yct8tUWv9I X-Google-Smtp-Source: AGHT+IHX0UdUWtQ72xYzwrwKupXY6k8LXulNXwTNic7MzbMFZJMQ2bIoXmmcJU9MOBRu2JB3EA6QtsTXaEiofJIPtcQ= X-Received: by 2002:a17:90b:5383:b0:33b:b0d6:6bc2 with SMTP id 98e67ed59e1d1-33bcf90923amr24293715a91.30.1761141370977; Wed, 22 Oct 2025 06:56:10 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Amit Langote Date: Wed, 22 Oct 2025 22:55:53 +0900 X-Gm-Features: AS18NWBkzfGSH7o5WGAo2FNZyRdtQz-LeYlFihirhgA6JxT30_tVBNGEeySHehE Message-ID: Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3 To: Pavel Stehule Cc: PostgreSQL-development , Junwang Zhao 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, Oct 21, 2025 at 2:10=E2=80=AFPM Pavel Stehule wrote: > =C3=BAt 21. 10. 2025 v 6:07 odes=C3=ADlatel Amit Langote napsal: >> >> On Thu, Apr 3, 2025 at 7:19=E2=80=AFPM Amit Langote wrote: >> > On Fri, Dec 20, 2024 at 1:23=E2=80=AFPM Amit Langote wrote: >> > > We discussed $subject at [1] and [2] and I'd like to continue that >> > > work with the hope to commit some part of it for v18. >> > >> > I did not get a chance to do any further work on this in this cycle, >> > but plan to start working on it after beta release, so moving this to >> > the next CF. I will post a rebased patch after the freeze to keep the >> > bots green for now. >> >> Sorry for the inactivity. I've moved the patch entry in the CF app to >> PG19-Drafts, since I don't plan to work on it myself in the immediate >> future. However, Junwang Zhao has expressed interest in taking this >> work forward, and I look forward to working with him on it. > > > This is very interesting and important feature - I can help with testing = and review if it will be necessary Thanks for the interest. Just to add a quick note on the current direction I=E2=80=99ve been discuss= ing off-list with Junwang: The next iteration of this work will likely follow a hybrid "fast-path + fallback" design rather than the original pure fast-path approach. The idea is to keep the optimization for straightforward cases where the foreign key and referenced key can be verified by a direct index probe, while falling back to the existing SPI path only when the runtime behavior of the executor is non-trivial to replicate -- such as visibility rechecks under concurrent updates -- or when the constraint itself involves richer semantics, like temporal foreign keys that require range and aggregation logic. That keeps the optimization safe without changing the meaning of constraint enforcement. This direction comes partly in response to the feedback from Robert and Tom in the earlier Eliminating SPI threads, who raised concerns that a fast path might silently diverge from what the executor does at runtime in subtle cases. The fallback design aims to address that directly: it keeps the optimization where it=E2=80=99s clearly safe, but defers to the existing SPI-based implementation whenever correctness might depend on executor behavior that would otherwise be difficult or risky to reproduce locally. In practice, this means adding a guarded fast path that performs the index probe and tuple lock directly under the same snapshot and security context that SPI would use, while caching stable metadata such as index descriptors, scan keys, and operator information per constraint or per statement. The fallback to SPI remains for the few cases that either depend on executor behavior or need features beyond a simple index probe: * Concurrent updates or deletes: If table_tuple_lock() reports that the target tuple was updated or deleted, we delegate to the SPI path so that EvalPlanQual and visibility rules are applied as today. * Partitioned parents: Skipped in v1 for simplicity, since they require routing the probe through the correct partition using PartitionDirectory. This can be added later as a separate patch once the core mechanism is stable. * Temporal foreign keys: These use range overlap and containment semantics (&&, <@, range_agg()) that inherently involve aggregation and multiple-row reasoning, so they stay on the SPI path. Everything else -- multi-column keys, cross-type equality supported by the index opfamily, collation matching, and RLS/ACL enforcement -- will be handled directly in the fast path. The security behavior will mirror the existing SPI path by temporarily switching to the parent table's owner with SECURITY_LOCAL_USERID_CHANGE | SECURITY_NOFORCE_RLS around the probe, like ri_PerformCheck() does. For concurrency, the fast path locks the located parent tuple with LockTupleKeyShare under GetActiveSnapshot(). If that succeeds (TM_Ok), the check passes immediately. While non-TM_Ok cases fall back for now, a later refinement could follow the update chain with table_tuple_fetch_row_version() under the current snapshot and re-lock the visible version, making the fast path fully self-contained. That=E2=80=99s the direction Junwang and I plan to explore next. -- Thanks, Amit Langote