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 1wi8ua-0002HW-19 for pgsql-hackers@arkaria.postgresql.org; Fri, 10 Jul 2026 10:56: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 1wi8uY-00HPge-1N for pgsql-hackers@arkaria.postgresql.org; Fri, 10 Jul 2026 10:56: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 1wi8uX-00HPgV-36 for pgsql-hackers@lists.postgresql.org; Fri, 10 Jul 2026 10:56:50 +0000 Received: from mail.postgrespro.ru ([93.174.132.70]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wi8uV-00000000dhm-1rAr for pgsql-hackers@postgresql.org; Fri, 10 Jul 2026 10:56:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1783681006; bh=w0AQjo0Btk0ilfKSyG94vmpz8FeOceaakXVOV7F2iTA=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Message-ID:From; b=vvCTtRB0TMhFBhVf3KY295hv1OulhujxlHuD7El863ALCuYT2psPFxmlBkJMidLmS 6kl9eVafOK/RBn8UUNvyL/MMFJs0anX8H1j9REYnT3iWRMi+MClQZdhDgv29NZQjuM 9f6ueO7tiVPyTiNJp4hk77iwctFkBxHQZJdRauEcj5AEy4aRcuJ+XYgBO37m8VN/hx KNgO6Hg6QAkEDAdq0lBDyOfTD31PfKgthPwVdx5imvPSUQxK5qK/hL65gWxYvhMrYf AiAP/vwE/tZT+/jfIVCnMVlJ4Xv+9pPEXej7Df6hK2birOEzA83LallJBm4r5MPSrD 4U0xeMlzKfynA== Received: from mail.l.postgrespro.ru (webmail-master-mstn.l.postgrespro.ru [192.168.2.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: g.kashkin@postgrespro.ru) by mail.postgrespro.ru (Postfix/587) with ESMTPSA id A612360ABE; Fri, 10 Jul 2026 13:56:46 +0300 (MSK) MIME-Version: 1.0 Date: Fri, 10 Jul 2026 13:56:46 +0300 From: Gleb Kashkin To: Alexander Korotkov Cc: pgsql-hackers Subject: Re: Bug in asynchronous Append In-Reply-To: References: Message-ID: <3a3f949c611835620cf675bdb989b1e7@postgrespro.ru> X-Sender: g.kashkin@postgrespro.ru Content-Type: multipart/mixed; boundary="=_7d28315ba4152126cc3971d2c48bdcbd" X-KSMG-AntiPhishing: NotDetected X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 3.0.0.9059, bases: 2026/07/10 10:01:00 #28419055 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=_7d28315ba4152126cc3971d2c48bdcbd Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8; format=flowed Alexander Korotkov писал(а) 2026-07-04 01:00: > Hi! > > ExecReScanAppend() unconditionally resets callback_pending for all > AsyncRequests. The problem is that postgres_fdw keeps its own > knowledge for the same fact: PgFdwConnState.pendingAreq – a pointer > to "pending async request" for a given connection. That connection > can be shared by several partitions/foreign tables (postgres_fdw > caches one connection per server+usermapping pair). The blind reset in > nodeAppend.c only touches the local AsyncRequest.callback_pending; it > never touches PgFdwConnState.pendingAreq, which correctly points to > the still-dangling request. > > Later, when another partition sharing that same connection gets its > own ReScan (for instance, its chgParam changed because of the LATERAL > parameter, and it already has a cursor open), it sends "CLOSE cursor" > via pgfdw_exec_query(). Before sending any new command on the > connection, that function first drains whatever request is still > outstanding on it: > > if (state && state->pendingAreq) > process_pending_request(state->pendingAreq); > > And process_pending_request() starts with: > > Assert(areq->callback_pending); > > – which fails, because the flag was corrupted some rounds earlier. > > The attached patch contains both the reproduction case and the fix. > The fix postpones the reset of the callback_pending flag to > ExecAppendAsyncBegin(). ExecAppendAsyncBegin() performs this cleanup > along with ExecReScan(), which completes the async fetch. > > ------ > Regards, > Alexander Korotkov > Supabase Hi! It seems, that there is a major issue with the patch, the draining doesn't throw away the result in cases when it is required. Consider this case: -- Expose stale rows from a pending async request that was valid for a -- previous rescan but is pruned out for the current one. CREATE VIEW base_tbl2_slow AS   SELECT t.a, t.b, t.c   FROM base_tbl2 t, LATERAL pg_sleep(0.2); ALTER FOREIGN TABLE async_p2 OPTIONS (SET table_name 'base_tbl2_slow'); SELECT o.x, s.a FROM (VALUES (2505), (3505)) o(x),   LATERAL (     SELECT a     FROM async_pt     WHERE a = o.x OR (o.x = 2505 AND a = 1505)     LIMIT 1   ) s ORDER BY o.x;   x   |  a    ------+------ 2505 | 1505 3505 | 2505 (2 rows) 1) Append executes two async fscans, one of which is slow 2) The first fscan finishes and the append execution stops due to LIMIT 1 3) Second fscan async request is still pending 4) Next append rescan prunes async_p2 for new outer value 5) Old async request for async_p2 is allowed to drain (receive a callback) 6) The stale tuple from async_p2 is accepted by Append, no pruning/filter check 7) We get a row that should be impossible (3505 | 2505) in this query See full reproducer in the attached patch. --=_7d28315ba4152126cc3971d2c48bdcbd Content-Transfer-Encoding: base64 Content-Type: text/x-diff; name=v1-regress.patch Content-Disposition: attachment; filename=v1-regress.patch; size=5051 ZGlmZiAtLWdpdCBhL2NvbnRyaWIvcG9zdGdyZXNfZmR3L2V4cGVjdGVkL3Bvc3RncmVzX2Zkdy5v dXQgYi9jb250cmliL3Bvc3RncmVzX2Zkdy9leHBlY3RlZC9wb3N0Z3Jlc19mZHcub3V0CmluZGV4 IGU5MDI4OWU0YWIxLi5lZWJkZjFjNGFkOCAxMDA2NDQKLS0tIGEvY29udHJpYi9wb3N0Z3Jlc19m ZHcvZXhwZWN0ZWQvcG9zdGdyZXNfZmR3Lm91dAorKysgYi9jb250cmliL3Bvc3RncmVzX2Zkdy9l eHBlY3RlZC9wb3N0Z3Jlc19mZHcub3V0CkBAIC0xMTY2MSw2ICsxMTY2MSwyMiBAQCBTRUxFQ1Qg KiBGUk9NIHJlc3VsdF90YmwgT1JERVIgQlkgYTsKICgzIHJvd3MpCiAKIERFTEVURSBGUk9NIHJl c3VsdF90Ymw7CistLSBDaGVjayB0aGF0IGEgcGVuZGluZyBhc3luYyByZXF1ZXN0IG9uIGEgc2hh cmVkIGNvbm5lY3Rpb24gaXNuJ3QgY29ycnVwdGVkCistLSB3aGVuIHRoZSBBcHBlbmQgaXMgcmVz Y2FubmVkIHdpdGggdGhlIHN1YnBsYW4gaG9sZGluZyBpdCBwcnVuZWQgb3V0LiAgSGVyZQorLS0g YXN5bmNfcDIgYW5kIGFzeW5jX3AzIHNoYXJlIGEgY29ubmVjdGlvbiwgYW5kIHBlciBvdXRlciBy b3cgZXhhY3RseSBvbmUgb2YKKy0tIHRoZW0gaXMgcHJ1bmVkIHdoaWxlIGFzeW5jX3AxIChhIGRp ZmZlcmVudCBjb25uZWN0aW9uKSBhbHdheXMgbWF0Y2hlczsgdGhlCistLSBpbm5lciBMSU1JVCBs ZWF2ZXMgdGhlIG90aGVyIHNoYXJlZC1jb25uZWN0aW9uIHJlcXVlc3Qgb3V0c3RhbmRpbmcgYWNy b3NzCistLSB0aGUgcmVzY2FuLCBhbmQgcmV1c2luZyB0aGF0IGNvbm5lY3Rpb24gZm9yIHRoZSBu ZXh0IHJvdW5kIG11c3QgZHJhaW4gaXQKKy0tIHJhdGhlciB0aGFuIHRyaXAgb3ZlciBzdGFsZSBz dGF0ZS4KK1NFTEVDVCBvLnggRlJPTSAoVkFMVUVTICgyNTA1KSwgKDM1MDUpKSBvKHgpLAorICBM QVRFUkFMIChTRUxFQ1QgYSBGUk9NIGFzeW5jX3B0IFdIRVJFIGEgPSAxNTA1IE9SIGEgPSBvLngg TElNSVQgMSkgcworT1JERVIgQlkgby54OworICB4ICAgCistLS0tLS0KKyAyNTA1CisgMzUwNQor KDIgcm93cykKKwogLS0gVGVzdCBDT1BZIFRPIHdoZW4gZm9yZWlnbiB0YWJsZSBpcyBwYXJ0aXRp b24KIENPUFkgYXN5bmNfcHQgVE8gc3Rkb3V0OyAtLWVycm9yCiBFUlJPUjogIGNhbm5vdCBjb3B5 IGZyb20gZm9yZWlnbiB0YWJsZSAiYXN5bmNfcDEiCmRpZmYgLS1naXQgYS9jb250cmliL3Bvc3Rn cmVzX2Zkdy9zcWwvcG9zdGdyZXNfZmR3LnNxbCBiL2NvbnRyaWIvcG9zdGdyZXNfZmR3L3NxbC9w b3N0Z3Jlc19mZHcuc3FsCmluZGV4IGRmYzU4YmViMGQyLi5jMThiNTRmMTc1NiAxMDA2NDQKLS0t IGEvY29udHJpYi9wb3N0Z3Jlc19mZHcvc3FsL3Bvc3RncmVzX2Zkdy5zcWwKKysrIGIvY29udHJp Yi9wb3N0Z3Jlc19mZHcvc3FsL3Bvc3RncmVzX2Zkdy5zcWwKQEAgLTM5OTcsNiArMzk5NywzOCBA QCBJTlNFUlQgSU5UTyByZXN1bHRfdGJsIFNFTEVDVCAqIEZST00gYXN5bmNfcHQgV0hFUkUgYiA9 PT0gNTA1OwogU0VMRUNUICogRlJPTSByZXN1bHRfdGJsIE9SREVSIEJZIGE7CiBERUxFVEUgRlJP TSByZXN1bHRfdGJsOwogCistLSBDaGVjayB0aGF0IGEgcGVuZGluZyBhc3luYyByZXF1ZXN0IG9u IGEgc2hhcmVkIGNvbm5lY3Rpb24gaXNuJ3QgY29ycnVwdGVkCistLSB3aGVuIHRoZSBBcHBlbmQg aXMgcmVzY2FubmVkIHdpdGggdGhlIHN1YnBsYW4gaG9sZGluZyBpdCBwcnVuZWQgb3V0LiAgSGVy ZQorLS0gYXN5bmNfcDIgYW5kIGFzeW5jX3AzIHNoYXJlIGEgY29ubmVjdGlvbiwgYW5kIHBlciBv dXRlciByb3cgZXhhY3RseSBvbmUgb2YKKy0tIHRoZW0gaXMgcHJ1bmVkIHdoaWxlIGFzeW5jX3Ax IChhIGRpZmZlcmVudCBjb25uZWN0aW9uKSBhbHdheXMgbWF0Y2hlczsgdGhlCistLSBpbm5lciBM SU1JVCBsZWF2ZXMgdGhlIG90aGVyIHNoYXJlZC1jb25uZWN0aW9uIHJlcXVlc3Qgb3V0c3RhbmRp bmcgYWNyb3NzCistLSB0aGUgcmVzY2FuLCBhbmQgcmV1c2luZyB0aGF0IGNvbm5lY3Rpb24gZm9y IHRoZSBuZXh0IHJvdW5kIG11c3QgZHJhaW4gaXQKKy0tIHJhdGhlciB0aGFuIHRyaXAgb3ZlciBz dGFsZSBzdGF0ZS4KK1NFTEVDVCBvLnggRlJPTSAoVkFMVUVTICgyNTA1KSwgKDM1MDUpKSBvKHgp LAorICBMQVRFUkFMIChTRUxFQ1QgYSBGUk9NIGFzeW5jX3B0IFdIRVJFIGEgPSAxNTA1IE9SIGEg PSBvLnggTElNSVQgMSkgcworT1JERVIgQlkgby54OworCistLSBFeHBvc2Ugc3RhbGUgcm93cyBm cm9tIGEgcGVuZGluZyBhc3luYyByZXF1ZXN0IHRoYXQgd2FzIHZhbGlkIGZvciBhCistLSBwcmV2 aW91cyByZXNjYW4gYnV0IGlzIHBydW5lZCBvdXQgZm9yIHRoZSBjdXJyZW50IG9uZS4KK0NSRUFU RSBWSUVXIGJhc2VfdGJsMl9zbG93IEFTCisgIFNFTEVDVCB0LmEsIHQuYiwgdC5jCisgIEZST00g YmFzZV90YmwyIHQsIExBVEVSQUwgcGdfc2xlZXAoMC4yKTsKKworQUxURVIgRk9SRUlHTiBUQUJM RSBhc3luY19wMiBPUFRJT05TIChTRVQgdGFibGVfbmFtZSAnYmFzZV90YmwyX3Nsb3cnKTsKKwor U0VMRUNUIG8ueCwgcy5hCitGUk9NIChWQUxVRVMgKDI1MDUpLCAoMzUwNSkpIG8oeCksCisgIExB VEVSQUwgKAorICAgIFNFTEVDVCBhCisgICAgRlJPTSBhc3luY19wdAorICAgIFdIRVJFIGEgPSBv LnggT1IgKG8ueCA9IDI1MDUgQU5EIGEgPSAxNTA1KQorICAgIExJTUlUIDEKKyAgKSBzCitPUkRF UiBCWSBvLng7CisKK0FMVEVSIEZPUkVJR04gVEFCTEUgYXN5bmNfcDIgT1BUSU9OUyAoU0VUIHRh YmxlX25hbWUgJ2Jhc2VfdGJsMicpOworRFJPUCBWSUVXIGJhc2VfdGJsMl9zbG93OworCiAtLSBU ZXN0IENPUFkgVE8gd2hlbiBmb3JlaWduIHRhYmxlIGlzIHBhcnRpdGlvbgogQ09QWSBhc3luY19w dCBUTyBzdGRvdXQ7IC0tZXJyb3IKIApkaWZmIC0tZ2l0IGEvc3JjL2JhY2tlbmQvZXhlY3V0b3Iv bm9kZUFwcGVuZC5jIGIvc3JjL2JhY2tlbmQvZXhlY3V0b3Ivbm9kZUFwcGVuZC5jCmluZGV4IDk4 NzM1OGUyN2ZhLi42YTVhMTRjZDU3NiAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvZXhlY3V0b3Iv bm9kZUFwcGVuZC5jCisrKyBiL3NyYy9iYWNrZW5kL2V4ZWN1dG9yL25vZGVBcHBlbmQuYwpAQCAt NDY5LDcgKzQ2OSwyMSBAQCBFeGVjUmVTY2FuQXBwZW5kKEFwcGVuZFN0YXRlICpub2RlKQogCQl7 CiAJCQlBc3luY1JlcXVlc3QgKmFyZXEgPSBub2RlLT5hc19hc3luY3JlcXVlc3RzW2ldOwogCi0J CQlhcmVxLT5jYWxsYmFja19wZW5kaW5nID0gZmFsc2U7CisJCQkvKgorCQkJICogTGVhdmUgYSBy ZXF1ZXN0IHRoYXQgaXMgc3RpbGwgbWFya2VkIGFzIHBlbmRpbmcgYSBjYWxsYmFjaworCQkJICog YWxvbmU6IGl0IG1heSBnZW51aW5lbHkgc3RpbGwgYmUgaW4gZmxpZ2h0LCBvciBpdCBtYXkgaGF2 ZSBhbgorCQkJICogdW5jb25zdW1lZCByZXN1bHQgYWxyZWFkeSBzaXR0aW5nIG9uIGEgY29ubmVj dGlvbiBzaGFyZWQgd2l0aAorCQkJICogYW5vdGhlciBzdWJwbGFuIChhcyBjYW4gaGFwcGVuIHdp dGggcG9zdGdyZXNfZmR3KS4gIEJsaW5kbHkKKwkJCSAqIGNsZWFyaW5nIGNhbGxiYWNrX3BlbmRp bmcgaGVyZSB3b3VsZCBkZXN5bmMgb3VyIGJvb2trZWVwaW5nCisJCQkgKiBmcm9tIHRoZSBhc3lu Yy1jYXBhYmxlIG5vZGUncyBvd24sIHdoaWNoIGNhbiBsZWFkIGl0IHRvCisJCQkgKiBtaXNoYW5k bGUgdGhhdCBjb25uZWN0aW9uIGxhdGVyIChlLmcuIHBvc3RncmVzX2ZkdyBhc3NlcnRzIHRoYXQK KwkJCSAqIGEgcmVxdWVzdCBpdCBzdGlsbCBjb25zaWRlcnMgaW4tcHJvY2VzcyBoYXMgY2FsbGJh Y2tfcGVuZGluZworCQkJICogc2V0KS4gIFN1Y2ggYSByZXF1ZXN0IGlzIGluc3RlYWQgZHJhaW5l ZCBsYXppbHksIHJpZ2h0IGJlZm9yZQorCQkJICogaXQgd291bGQgYmUgcmV1c2VkLCBpbiBFeGVj QXBwZW5kQXN5bmNCZWdpbigpLgorCQkJICovCisJCQlpZiAoYXJlcS0+Y2FsbGJhY2tfcGVuZGlu ZykKKwkJCQljb250aW51ZTsKKwogCQkJYXJlcS0+cmVxdWVzdF9jb21wbGV0ZSA9IGZhbHNlOwog CQkJYXJlcS0+cmVzdWx0ID0gTlVMTDsKIAkJfQpAQCAtOTE1LDcgKzkyOSwyNSBAQCBFeGVjQXBw ZW5kQXN5bmNCZWdpbihBcHBlbmRTdGF0ZSAqbm9kZSkKIAkJQXN5bmNSZXF1ZXN0ICphcmVxID0g bm9kZS0+YXNfYXN5bmNyZXF1ZXN0c1tpXTsKIAogCQlBc3NlcnQoYXJlcS0+cmVxdWVzdF9pbmRl eCA9PSBpKTsKLQkJQXNzZXJ0KCFhcmVxLT5jYWxsYmFja19wZW5kaW5nKTsKKworCQkvKgorCQkg KiBUaGlzIHJlcXVlc3QgbWF5IHN0aWxsIGJlIG1hcmtlZCBhcyBwZW5kaW5nIGEgY2FsbGJhY2ss IGlmCisJCSAqIEV4ZWNSZVNjYW5BcHBlbmQoKSBsZWZ0IGl0IGFsb25lIGJlY2F1c2UgaXQgbWln aHQgaGF2ZSBiZWVuCisJCSAqIGdlbnVpbmVseSBpbiBmbGlnaHQgKG9yIGhhZCBhbiB1bmNvbnN1 bWVkIHJlc3VsdCB3YWl0aW5nIG9uIGEKKwkJICogY29ubmVjdGlvbiBzaGFyZWQgd2l0aCBhbm90 aGVyIHN1YnBsYW4pLiAgRHJhaW4gaXQgbm93LCBiZWZvcmUKKwkJICogcmV1c2luZyBpdDogRXhl Y1JlU2NhbigpIGxldHMgdGhlIGFzeW5jLWNhcGFibGUgbm9kZSBzZXR0bGUgYW55CisJCSAqIHN1 Y2ggb3V0c3RhbmRpbmcgc3RhdGUgKGUuZy4gcG9zdGdyZXNfZmR3J3MKKwkJICogcG9zdGdyZXNS ZVNjYW5Gb3JlaWduU2NhbigpIHdpbGwgd2FpdCBmb3IgYW4gaW4tcHJvZ3Jlc3MgcmVxdWVzdCBv bgorCQkgKiBpdHMgb3duIGNvbm5lY3Rpb24gYW5kIGNvbnN1bWUgaXRzIHJlc3VsdCksIGFmdGVy IHdoaWNoIGl0J3Mgc2FmZQorCQkgKiB0byByZXNldCBvdXIgb3duIGJvb2trZWVwaW5nIGFuZCBp c3N1ZSBhIGZyZXNoIHJlcXVlc3QuCisJCSAqLworCQlpZiAoYXJlcS0+Y2FsbGJhY2tfcGVuZGlu ZykKKwkJeworCQkJRXhlY1JlU2Nhbihub2RlLT5hcHBlbmRwbGFuc1tpXSk7CisJCQlhcmVxLT5j YWxsYmFja19wZW5kaW5nID0gZmFsc2U7CisJCQlhcmVxLT5yZXF1ZXN0X2NvbXBsZXRlID0gZmFs c2U7CisJCQlhcmVxLT5yZXN1bHQgPSBOVUxMOworCQl9CiAKIAkJLyogRG8gdGhlIGFjdHVhbCB3 b3JrLiAqLwogCQlFeGVjQXN5bmNSZXF1ZXN0KGFyZXEpOwo= --=_7d28315ba4152126cc3971d2c48bdcbd--