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.98.2) (envelope-from ) id 1xBz1U-00000003UXO-0waB for pgsql-hackers@arkaria.postgresql.org; Wed, 30 Sep 2026 18:27:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xBz1T-00000003b2I-0Gw2 for pgsql-hackers@arkaria.postgresql.org; Wed, 30 Sep 2026 18:27: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.98.2) (envelope-from ) id 1xBz1S-00000003b25-2Q2y for pgsql-hackers@lists.postgresql.org; Wed, 30 Sep 2026 18:27:18 +0000 Received: from mail-ua2-x0d.google.com ([2a00:1450:4864:39::d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1xBz1P-0000000291N-3nzy for pgsql-hackers@lists.postgresql.org; Wed, 30 Sep 2026 18:27:18 +0000 Received: by mail-ua2-x0d.google.com with SMTP id a1e0cc1a2514c-98a86b36f81so104585241.0 for ; Wed, 30 Sep 2026 11:27:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790792834; x=1791397634; darn=lists.postgresql.org; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-type:content-transfer-encoding:mime-version:from:to:cc :subject:date:message-id:reply-to:content-type; bh=mQdQyuU4snzcUPSwocy0ffNJU94fuCwa9tCV7lpYI0E=; b=Z/V3TYLWlB7cEdf6j7l3pjdb4/62c5KGdpEeWQhsWvt8KkLr2YujB/2237YYdw3pwo N/cheCSApwtN63k2NwT7YKQY7KbOO6MjdZpQdtsi38mZIakR4XBD3QKhg708WqjNKNYp xhX0fx5xtpn3tuAox24rUGBRBB6TnTE9hsVRBulu+KyXuP2Fjza6AR+cDXW1oLRyhCeF wzQxILjo/XUFG4KnDvjcgkxprvLWTBujy7vhRWMNIxz9meQJydVS9GmlUUtP1wTNzpqh dWPllScgRQ1aemW66wDdaz86YW4LFTlOhybQabS1g6/bjfxA1JbdLEoHvLx7gXMu9hLW c0kQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790792834; x=1791397634; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-type:content-transfer-encoding:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=mQdQyuU4snzcUPSwocy0ffNJU94fuCwa9tCV7lpYI0E=; b=rjLKDDINySc8cqAdeboKKEq1Sy//eIayUob+7eGTMDqGcTC1BSzhj1G6zcPdqJ9dUX YwxXZZNxsouYLKu4Ft1+m30huFJ5qx83prNW9AR5X3KQYJY0GDN4ZtSL5dnYD18qJNTT 2UDIwNyrvXDNiBN12I3pOAQyziCT8YdW+A4vnRPLN7JFxdfqcFagG5nD6lvccsdq7F53 tnp09StklsPxfkXSFtKw5JDOovErynxcJCGqgOOQX8/KshflLFtaNWEdaCFe4orBLivf YKhMMyTqhjxPp08vUnqkO/uaHnd0rVW7VGEdBJ5sO3w81/hbjrbDDCvbBfqVKwl61QQb 2x8w== X-Gm-Message-State: AFq9FYJubF2oIjveXTXkAhQbZUPPFMIZcdfI1yaa2slU1uPyQ+UFVd4i GzAS3GRzb7K4CFY50spk2QEF4DGp3s1nAs62h5NgXk1RvcELgFm32QmD X-Gm-Gg: AYBFou08D1R1tKaXq62Z1GwbrEkN7HlWWvrdiaaAJ74Hl8W3nXkCgNblWvUqFykHlKi r/18KCPnPHnHnJmENtaGUFJ7DERbJC/0FxFNu49B3Gv4thR6OzTZo+qXjFNaut8edGZCJ4YX4Kk /FK2pEqJs10Z7IAQdy5muEWWx5uMadu9FOX8Tzo3r5yvEVLOtCLHpJHZj/paJSjJf+no6JgsR7K 1MFGOjiZGFJrvNTZomFBv2DBWBmCOn2c7N0YysgitfUQYTcEQB8g+XPHID/UHEEWC9I6V0OGzo1 eHzYm2KrxNS/ZHHU8VofwwvG0iefzRFQLFVa/GKbTQYQNL30DcQZRNHwcFuEYZHK8KNBo2Fwf5Q 3PHijO+FAEN2yFCh72zA91jhN8mn17w6KbXcYWpnqftbEuksuKjZXoWY9LLUNf5lGnacIDY8UTv xMjNkl8nGKqU/hxhE/Z3p4a7NcgV+NhuLVUSAyMYYFrhwUfRuTLHZ2MY+dXiVmoUdKxWEV4bGiS 2jwnSmcH51K0NPCqz4A X-Received: by 2002:a05:6102:5122:b0:7b2:43df:ca4d with SMTP id ada2fe7eead31-7be74093788mr558374137.32.1790792833977; Wed, 30 Sep 2026 11:27:13 -0700 (PDT) Received: from localhost ([2804:14d:32a7:4273:54c6:83de:ae28:8367]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-98a870a63d2sm701395241.7.2026.09.30.11.27.12 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 30 Sep 2026 11:27:13 -0700 (PDT) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Wed, 30 Sep 2026 15:27:10 -0300 Message-Id: Cc: "PostgreSQL Hackers" Subject: Re: postgres_fdw: transaction mode inheritance corner cases From: "Matheus Alcantara" To: "Etsuro Fujita" , "Fujii Masao" X-Mailer: aerc 0.21.0 References: In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed Sep 30, 2026 at 7:45 AM -03, Etsuro Fujita wrote: > Attached is a patch for that. I will add test cases for these in the > next version. > Hi, thanks for the patch! I tested it and I think that I may have found two issues: 1: read-write local transactions can no longer query a hot standby If I create a foreign server pointing to a standby, sending an explicit READ WRITE makes the standby reject the remote START TRANSACTION. A plain SELECT from a foreign table on a standby now fails, including in autocommit, because the local transaction is read-write by default. It works on unpatched master. Repro: -- on the primary (port 5433 is running a standby server) create extension postgres_fdw; create table t(a int); insert into t values (1),(2); create server sb foreign data wrapper postgres_fdw options (dbname 'postgres', port '5433'); create user mapping for current_user server sb; create foreign table fsb(a int) server sb options (table_name 't'); select * from fsb; ERROR: 0A000: cannot set transaction read-write mode during recovery CONTEXT: remote SQL command: START TRANSACTION ISOLATION LEVEL REPEATABLE = READ READ WRITE NOT DEFERRABLE begin read only; select * from fsb; -- works commit; I'm not sure how much common is querying a standby through postgres_fdw, but I've already seen some cases, so I'm wondering if this needs some handling, what do you think? 2: a foreign cursor first fetched in a rolled-back savepoint breaks at COMM= IT Repro: begin; declare c cursor for select * from ft; savepoint s1; fetch 1 from c; rollback to s1; fetch all from c; commit; ERROR: 34000: cursor "c1" does not exist CONTEXT: remote SQL command: CLOSE c1 This also works on unpatched master. There, the remote cursor is created lazily at the first FETCH, without a remote savepoint, so it lives at remote level 1 and survives ROLLBACK TO s1. With the patch, the new begin_remote_xact() call in create_cursor opens a remote SAVEPOINT s2 and creates the cursor inside it. ROLLBACK TO s1 then destroys the remote cursor while the local side still thinks it exists. If the first FETCH happens before the savepoint, the same script works with the patch. I think the remote cursor needs to be created at the level where the scan started, or the remote/local cursor state needs to be reconciled some other way. Also, I didn't tested this case but on execute_foreign_modify and direct-modify results are read without going through begin_remote_xact(). So I'm wondering if a volatile function that runs SET TRANSACTION READ ONLY in the middle of a single INSERT ... SELECT f() could bypass the sync. -- Matheus Alcantara EDB: https://www.enterprisedb.com