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 1whh8y-000Mum-23 for pgsql-bugs@arkaria.postgresql.org; Thu, 09 Jul 2026 05:17:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1whh8x-00B0Sg-0h for pgsql-bugs@arkaria.postgresql.org; Thu, 09 Jul 2026 05:17:51 +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.96) (envelope-from ) id 1whh8L-00AyXa-2P for pgsql-bugs@lists.postgresql.org; Thu, 09 Jul 2026 05:17:14 +0000 Received: from mail-ej1-x634.google.com ([2a00:1450:4864:20::634]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1whh8J-00000000PRi-14CU for pgsql-bugs@lists.postgresql.org; Thu, 09 Jul 2026 05:17:14 +0000 Received: by mail-ej1-x634.google.com with SMTP id a640c23a62f3a-c127ec4447cso66012266b.2 for ; Wed, 08 Jul 2026 22:17:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=garret-ru.20251104.gappssmtp.com; s=20251104; t=1783574230; x=1784179030; darn=lists.postgresql.org; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:from:to:cc:subject:date:message-id:reply-to :content-type; bh=VwbVxx/gItm85QfQ4cSPxhGy7RZaVsd4t9lP37TnHX4=; b=PRJ35Kw9VBAR/h7CcC+lfFskQPgbv7w+eVDN696RTnpxO+CxbR75UpfzA/qM0hITdd BdRWhJPHsdX/tAPvQZbVXl9ybbbVKIEariZqwePylaImApUaoVwdeqwGX2sdsPocYfGN iMLi6UJomDRrc8gNvZTe0p7hJaTrEIvRMGCfg4wxzEKnRvqbAM/0zsCbqR5Yg6X9I+1L joBg12hZfZ7oulMJuZU9DzoSzP73I4syjwFDtttE+3m7psOIR931fcPfRMSLei/ehSSW tGaikeQ50M8eL8peuRX4Ibo9yI/QMD3VjU34bYJxnq5Chwo9ZJ6tLU0b30E/yVHDAQVy ChgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783574230; x=1784179030; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VwbVxx/gItm85QfQ4cSPxhGy7RZaVsd4t9lP37TnHX4=; b=TL/hg+jVs2bFybUXev6hgPL5QZJMYs7ca3KhMJ/P4WxLIsBjCWPyIgRJiDGqsDgO74 EidtVN6OakpTsfOBDQt5+t57N7F7yBJcg2DxYrXWrHjFELIpDDV3vAKUq2PXyk8FBmdg 1xob17z1og7LGoKA8qemcOa0lwYK7HNez9D1WzzjC+bzygNwBDw4qUktP26hTcTRAis8 DjH+5KIsoRdyG6pmkypK+rgs6h2V+ZGatYOpVn6EpUt9ysHueKRdc6jshiwRSqll4j8a DJPO9ymyrIiOsfgx7dh7+qUE1BO7Xnh0HpPX2I7A5l25SDe//YV3ZmXrXHZS8z2+ZVtV vFxg== X-Forwarded-Encrypted: i=1; AHgh+RpYDyyEG8x4uP9Rl8ySePHOYLMXpIcgOy8qmEydcW2scSeeEOTVt2GIdV7nSqYDbiFcKEKIQalfHth+@lists.postgresql.org X-Gm-Message-State: AOJu0Yz+hEY748ijwB9hoP59h3VWKFqo4Fiaz2ZCJA1eaBbx3R7Gr00v M90iEhngAN+VJVhqW3AP7BygDrk8eNJf3g3/gdnrwwVtlO0jwgnyQw4Jzj1r0hAN8Q== X-Gm-Gg: AfdE7clzhXiafPW+XYqR5xF0rSmEvo8a+lb7RBnkfF1Wylw1swbDoxCU0NCGp2qbfij ZXoWHEIyTfAiujeOYureDB1vE95lEelbXOwtuhhheIsBKwcBu3pn4sGcV1c4mXfBh3kcwKob2xE lTGpgXKx4YJMQhTWG8pvG6+IZSIW1UHX96ZIPdJ4sjAg3xdWkvKU89DcKr5EABzFukRoUuPubP/ ewLTliFDurulPJ07iNbeBK3ibk+bJe7OS8cBaw94e6pWZOH8fbjvb+708Ya2pce/Egx0rfnQx0W s8hrviQGQVIKFMcObJwcv/VNBeps+g2LrDhNbR/58qfwUeSHTz/WkJnkMMW4vdcX+gt7wqdUZOC L8hj8n61cZDeL1xTHabiOz4W9wgHGtQbqGdDRsjAabx5dcdRy0Sfp3ej3tIPLm8Q+utYgcUXRbQ e6ld/8OzecajQ1t0xHHVlC+vwMdw== X-Received: by 2002:a17:907:3e25:b0:c12:9471:e231 with SMTP id a640c23a62f3a-c15ce0b462amr267800666b.35.1783574230067; Wed, 08 Jul 2026 22:17:10 -0700 (PDT) Received: from [10.248.56.12] ([130.41.208.1]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c15d5de95e6sm168353566b.39.2026.07.08.22.17.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 08 Jul 2026 22:17:08 -0700 (PDT) Message-ID: <21477053-efd1-485a-8f72-c2e292fcf2a0@garret.ru> Date: Thu, 9 Jul 2026 08:17:06 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: BUG #19519: REPACK can fail due to missing chunk for toast value To: Heikki Linnakangas , Michael Paquier , Srinath Reddy Sadipiralla Cc: Matthias van de Meent , Imran Zaheer , Alexander Lakhin , PostgreSQL mailing lists References: Content-Language: en-US From: Konstantin Knizhnik In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 08/07/2026 3:00 PM, Heikki Linnakangas wrote: > On 08/07/2026 04:10, Michael Paquier wrote: >> On Wed, Jul 08, 2026 at 07:15:16AM +0900, Michael Paquier wrote: >>> One thing that I still don't like much in the patch as written is my >>> use of a missing_ok argument, which feels super confusing as it >>> applies only to the underlying external TOAST, if the relation has >>> any.  I'd be tempted to rewrite this portion of the patch with a >>> uint32 flags.  Even if we assign one value for now (say MISSING_TOAST, >>> MISSING_TOAST_OK or whatever), it would allow more flexibility on ABI >>> grounds if we want more like states in the future across this portion >>> of the stack.  Again, I strongly doubt that we will be able to >>> backpatch any of that. > > Yeah, boolean arguments in general can be confusing. Especially > arguments like "missing_ok" where it's hard to remember which behavior > is true and which is false. An IDE that shows the name of the argument > helps, but having the caller say "MISSING_TOAST_OK" rather than "true" > is much clearer. > > For backpatching, I think we could smuggle the flag in a global > variable, to avoid changing the signature of the > relation_fetch_toast_slice() callback. See attached patch 0002 on top > of your 0001 patch (which is also attached for completeness). It > doesn't fix the problem for hypothetical 3rd party tableam > implementations that implement their own relation_fetch_toast_slice() > callback. But do such extensions even exist? If yes, they could be > fixed too by also checking the global variable. > > I thought about adding an extra "extended" callback next to > relation_fetch_toast_slice(), but I don't see a way to add functions > to TableAmRoutine in an ABI-compatible way. For the future, we might > want to store sizeof(TableAmRoutine) in the struct itself, so that we > could add fields to it in minor versions without breaking the API, in > case we need something like this again. Changing `table_relation_fetch_toast_slice` signature breaks compatibility with some extensions, for example duckdb. I wonder if we can change only  `bool (*relation_fetch_toast_slice)(..., bool missing_ok)` callback signature, but preserve signature of `table_relation_fetch_toast_slice`, adding one more function `table_relation_try_fetch_toast_slice`: static inline void table_relation_fetch_toast_slice(Relation toastrel, Oid valueid,                                                       int32 attrsize, int32 sliceoffset,                                                       int32 slicelength, varlena *result,                                                       bool missing_ok) {       (void)toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid, attrsize, sliceoffset, slicelength, result, false); } static inline bool table_relation_try_fetch_toast_slice(Relation toastrel, Oid valueid,                                                       int32 attrsize, int32 sliceoffset,                                                       int32 slicelength, varlena *result,                                                       bool missing_ok) {     return toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid, attrsize, sliceoffset, slicelength, result, missing_ok);  } > >> A couple of extra notes while I do not forget about that stuff..  The >> patch may be better split into two if we go with this approach, as the >> index build and rewrite paths require different solutions: >> - One for the rewrite path.  It makes little sense to do any kind of >> aggressive early detoasting because it may be wasteful due to the >> tuple rewrites that update their data with only copies by reference >> (main relation tuple is rewritten, reuses the same external TOAST >> tuple).  For workloads where UPDATEs do not touch the TOASTed >> attributes, that would be a waste. > > I didn't understand this part. Do you mean when rebuilding the indexes > after rewriting the heap? I didn't think we support storing toasted > external datums in an index at all. > >> - One for the index build path, which is actually too aggressive with >> its early detoasting, now that I think about it.  There should be no >> need to perform a detoast for anything else than the attributes that >> are used in the index definition or the attributes that are used in >> index expressions.  So as written this patch would lead to a >> regression. > Yeah, although I wouldn't be too worried about the performance here. > The penalty would be when building an index on values that are large > enough to be toasted, with lots of RECENTLY_DEAD tuples. That doesn't > seem like a very common case. > > - Heikki