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 1v6b5j-00720O-SU for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Oct 2025 20:48:56 +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 1v6b5h-00D3fb-Cw for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Oct 2025 20:48:54 +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 1v6b5h-00D3fP-3O for pgsql-hackers@lists.postgresql.org; Wed, 08 Oct 2025 20:48:54 +0000 Received: from mail-il1-x132.google.com ([2607:f8b0:4864:20::132]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1v6b5f-0016P5-2Q for pgsql-hackers@postgresql.org; Wed, 08 Oct 2025 20:48:53 +0000 Received: by mail-il1-x132.google.com with SMTP id e9e14a558f8ab-42486ed0706so1821295ab.0 for ; Wed, 08 Oct 2025 13:48:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759956529; x=1760561329; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=qVClSUiy8WdFhnqVb3KblOlusJRezbq+RZ2FFBcNQao=; b=XyXulBQPRYD4jZ9PHWvd5pT2iaGnjuaM4WzPKpPJpWgv1jBPo9GfJQ9PDdxhlK3Xp3 tgBMJuMxifbSQw0No034pKJRJNchD2mcOIXZjYrIBA5n16RbuMFmT/NvrcqP4FH6Pudy iaU6W1TTJ8mJMtU1dghXE3vO64+tFgPsMWZSTFcU94k4zVvbP/kMqD1XtX/qm3TI8ITb TOwNXx7BbLeeA/Qq/EBGglLwYVTKYe2WtcDqXcbFLugoDkdWVjUfHJgcIItPeqxASWka g11iGhv5kPycAmZ1WuMVt4XB44eWb9TMx663dP4pY4koidXQ2j1y6VwOKk2Xu7oU+B6l G8TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759956529; x=1760561329; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=qVClSUiy8WdFhnqVb3KblOlusJRezbq+RZ2FFBcNQao=; b=vS1VycbRvyeoIWYSVMwiFKr35V0Pki7NAibBKU5cVDpLZIgEMDcmKX+nBI0Ws35sd4 CgPjIpIPA1FoYD1XrbadohHWzZlCiXk8bgLHPlf7MdUvZLf9sGEKwlnPqq0ZTypINLZv rPZQRlTQK29zXQJDOpD3o2XReqvavhsBF7/fYt3MWTAcGr+NEjEV9KEcYO18L35llZF5 UG3IGkS52v0A+V0bv+vPT8MhxLj/5ojV0o3WOrtO32iKyCYhg5JpDadlRxIps2b4DMIM ixjqT8n5CfcIvCwE83XMo6QqdQr5AWfRerbFBGehsI8kDT5aDLkwINsBOCpn/HbKNW5k 7RDw== X-Forwarded-Encrypted: i=1; AJvYcCXeWcgDHr86KQaTSVTwAh6dWbWXia2g0Gipy8ILcRYLIt4M5bHODuwk+Ep7avpItuOBYFLRWe/Y0DV0Ihyq@postgresql.org X-Gm-Message-State: AOJu0YxhPNOf6Hq8iMdfn3H0+wzBo3fBbLMv026R9Vb/WBC/hITUOEV4 NCF7SeHoLQCw1G3rpJqyrgwX6jfkFNaOSA7k17h9nfQRuKuxQFHK64r+ X-Gm-Gg: ASbGncuwsj8kZsOsFT4p5QY4Swkl77EV50tIHK53q78adRQfm8dL+uK7OPhzNr/BhtS 2rvVcvcL5TD77WQpk5BlsW0ROdyWAcEFncYElqvK2IEMushMjsrBkj5/4IOjayryWy9K8NCupfo 2XcnMSJQAgKrPerw3lbuXEZ1XO9hB8AxLtOS5rK9mqQzIUqgOUuKaDD8UJUK+hnwPkngdw/cy1L 8qY67KnJzC+IfNkhoR1utlQmypHOulbXlOz1x4ds39Y/7tYO75BPpC6acFybkNy1mzp21POPVRW Ga53qYUaijNc6JyMX1G5ZKqBl3tg+keDPRefEA9+0fefQZoMGNxcQuq7cxcNeXvoTtvqoq0Who1 9XRquwj6qrPKjn/Bsj3JGKwHIYJB+vZ+U0LGum1nPPB+lZM8kUy+L4gxPq8WIrn6WJEfEcSMb3M 5p2X8mZiSRq/Fmeo1lxGagWx1QSiM1L0Y9NrCz X-Google-Smtp-Source: AGHT+IF7AIraaH/BdgKLxwfrhun9aR/E/OT1IxVw3WbtjJ8Si6Yn4nPcwZMKk2zW6mfuP6WgrYgkdA== X-Received: by 2002:a05:6e02:168e:b0:425:73c6:9041 with SMTP id e9e14a558f8ab-42f873d1182mr46203245ab.17.1759956529189; Wed, 08 Oct 2025 13:48:49 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-57b5ea3a5basm7593391173.23.2025.10.08.13.48.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Oct 2025 13:48:48 -0700 (PDT) Date: Wed, 8 Oct 2025 15:48:46 -0500 From: Nathan Bossart To: Greg Burd Cc: "Burd, Greg" , "pgsql-hackers@postgresql.org" Subject: Re: Expanding HOT updates for expression and partial indexes Message-ID: References: <97f0aa72-f172-4673-8b04-533f022c3149@app.fastmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, Oct 07, 2025 at 05:36:11PM -0400, Greg Burd wrote: > I put the patch aside for a while, then this past week at PGConf.dev/NYC > I heard interest from a few people (Jeff Davis, Nathan Bossart) who > encouraged me to move the code executing the expressions to just before > acquiring the lock but after pinning the buffer. The theory being that > my new code using the old/new tts to form and test the index tuples > resulting from executing expressions was using the resultsRelInfo struct > created during plan execution, not the information found on the page, > and so was safe without the lock. An open question (at least from me) is whether this is safe. I'm not familiar enough with this area of code yet to confidently determine that. > After reviewing how updates work in the executor, I discovered that > during execution the new tuple slot is populated with the information > from ExecBuildUpdateProjection() and the old tuple, but that most > importantly for this use case that function created a bitmap of the > modified columns (the columns specified in the update). This bitmap > isn't the same as the one produced by HeapDetermineColumnsInfo() as the > latter excludes attributes that are not changed after testing equality > with the helper function heap_attr_equals() where as the former will > include attributes that appear in the update but are the same value as > before. This, happily, is immaterial for the purposes of my function > ExecExprIndexesRequireUpdates() which simply needs to check to see if > index tuples generated are unchanged. So I had all I needed to run the > checks ahead of acquiring the lock on the buffer. Nice. > There is much room for improvement, and your suggestions are welcome. A general and predictable suggestion is to find ways to break this into smaller pieces. As-is, this patch would take me an enormous amount of time to review in any depth. If we can break off some smaller pieces that we can scrutinize and commit independently, we can start making forward progress sooner. The UpdateContext and reloption stuff are examples of things that might be possible to split into independent patches. > I'll find time to quantify the benefit of this patch for the targeted > use cases and to ensure that all other cases see no regressions. Looking forward to these results. This should also help us decide whether to set expression_checks by default. > I added a reloption "expression_checks" to disable this new code path. > Good idea or bad precedent? If there are cases where the added overhead outweighs the benefits (which seems like it must be true some of the time), then I think we must have a way to opt-out (or maybe even opt-in). In fact, I'd advise adding a GUC to complement the reloption so that users can configure it at higher levels. > In execIndexing I special case for IsolationIsSerializable() and I can't > remember why now but I do recall one isolation test failing... I'll > check on this and get back to the thread. Or maybe you know why that I didn't follow this. > I'd like not to build, then rebuild index tuples for these expressions > but I can't think of a way to do that without a palloc(), this is > avoided today. Is the avoidance of palloc() a strict rule? Is this discussed in the code anywhere? -- nathan