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 1vEd2k-00EXK3-Ug for pgsql-bugs@arkaria.postgresql.org; Fri, 31 Oct 2025 00:31:02 +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 1vEd2i-00BF4H-Hq for pgsql-bugs@arkaria.postgresql.org; Fri, 31 Oct 2025 00:30:59 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vEd2i-00BF47-6R for pgsql-bugs@lists.postgresql.org; Fri, 31 Oct 2025 00:30:59 +0000 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vEd2f-004eHl-18 for pgsql-bugs@lists.postgresql.org; Fri, 31 Oct 2025 00:30:58 +0000 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-29525e6d98bso1356555ad.1 for ; Thu, 30 Oct 2025 17:30:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761870656; x=1762475456; darn=lists.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=GnlSgdIZzdKKZ08N8joOTXihntIF/JCkMiz4bgIqDxk=; b=Evickm+IFEAacgVHhSDdlciBFwU6Aldabk4Gh0U4jCXwtTGgSS2GEwbDu6s5VI6/vE 4y7aY8ver9oFLCfjySUTCMGGKTbB0K/15x9TOMAlrFrfKRI6Aqves0rGALZrhWtUHeXz eXytMlY19HT7V5Th16g6jybYGSUNFJ/RGSIXAteqMr+hvGMwS2F2/AQLO/Vc+RwUYH4f OOGTbUWBgVOlJ535ktyTgo7RBr0moDNSDrCgRtxDJW/rK2zI3Cdb1ugCGhO6nmvgYoep VXOoHSxdtO5qUjTEBLczDKSO1mKxOFJ7K1yVp4FlDyYOXHGvmfD9wV30YzBh60zaLz8d f7PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761870656; x=1762475456; 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=GnlSgdIZzdKKZ08N8joOTXihntIF/JCkMiz4bgIqDxk=; b=e3CUwxMdKiQiWMZu217VD4PyzU7XBUitWjfQQoILxXlgJWWAHes6iXvIZfuSoslPMP CkvWpX1frWJJ1ejGT4SVPUg7ayiHtvE7L9jL8k7EBOvk/jkxRBuUslVB/g4V7k2M3NWE 5fv8nhUmrFpaTExgvun+MMGu1E9JBRtaau1rQspls513wfid9CHHiXLhqSM8Tx1ASa+l TRTdS8nmuy4FL0+0/o5BxORWkPO6YfViUTT7L0JNoj6utogiKDLvFVH6Jid2oMTkFr6U E4rD4q+fVTJNtdxhGIrVu6F32em0WYyA+Z5hlPKzxXM0kcNQBR5hmmjl+l7YTxP9Jmil 5XKw== X-Forwarded-Encrypted: i=1; AJvYcCVkkIYui+Ieq8nZlMd00FwAqwoav11iHr7utuZqovSWOzqZCA6y6oB70bwAqCBkcaSkJCu5YmcyO3Yr@lists.postgresql.org X-Gm-Message-State: AOJu0Yyzcx95LFk2AD8nJAc2YMCtyMYC0fXQ/X8UpOPbgQgtseQyx/eO wSSx7OMLAWKXMWZ6fhzECrqkIfCGw+deCEEqB1ZkdcauuLhhxSYYCSblvh0cgdyta+lOWUiNNLz x3MQgNLnNo7w8E+V3JzDAvFV+CSl2Fgk= X-Gm-Gg: ASbGncsxpKicWrwhRDCWIXmC7nKzRcAZaR364OaNLCNLbndOtns9nugnJcy0j96JnVP 9EHhpGZChly5u6yXCfLiv+qIjjbxQHauHDcVSjZBTAYZ8Muq/wjCndjSOm5VvPlcq1P+UnbamVK KifaDrFD5+m8UcW8hirKEg867xHgvQA51vzS9/9BpDthoYIsJSpW8CIWqz8fRvKjvm8mBP+8RfC QVxTSwJZOwMPCHatbAptpwueNqAR8TJq0fvywOrW+GOxMGWCuFxtar8+vfi/g== X-Google-Smtp-Source: AGHT+IHZrkeRFV/dI5JuI3RVazmnS2t+lbxbc/N/loCL96KtDSTqVL2+qj4AKAOhfxpjcZHMnK+ZdUvVRREIK3BmpMw= X-Received: by 2002:a17:902:b588:b0:27c:a35a:1321 with SMTP id d9443c01a7336-2951a5c28c1mr16307555ad.51.1761870655829; Thu, 30 Oct 2025 17:30:55 -0700 (PDT) MIME-Version: 1.0 References: <19099-e05dcfa022fe553d@postgresql.org> <2960545.1761800903@sss.pgh.pa.us> <3017911.1761832112@sss.pgh.pa.us> In-Reply-To: <3017911.1761832112@sss.pgh.pa.us> From: Amit Langote Date: Fri, 31 Oct 2025 09:30:39 +0900 X-Gm-Features: AWmQ_bmaa4UqjmustLbkjg3Ozh6rTbyRAdClseVRaEve0eYQmq0Y8jgx8zRTdnE Message-ID: Subject: Re: BUG #19099: Conditional DELETE from partitioned table with non-updatable partition raises internal error To: Tom Lane Cc: Kirill Reshke , Tender Wang , jian he , exclusion@gmail.com, pgsql-bugs@lists.postgresql.org 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 Thu, Oct 30, 2025 at 10:48=E2=80=AFPM Tom Lane wrote= : > Kirill Reshke writes: > > Tom wrote: > >> It's surely pretty accidental (and arguably not desirable) > >> if "DELETE FROM pt WHERE false" doesn't fail the same way. > > > I cannot prove to myself why failing here is actually desirable. Can > > you elaborate? > > If we throw that failure in some cases but not others, we're exposing > implementation details. > > The definition could have been "throw 'cannot delete from foreign > table' only if the query actually attempts to delete some specific > row from some foreign table", but it is not implemented that way. > Instead the error is thrown during query startup if the query has > a foreign table as a potential delete target. Thus, as things stand > today, you might or might not get the error depending on whether > the planner can prove that that partition won't be deleted from. > This is not a great user experience, because we don't (and won't) > make any hard promises about how smart the planner is. > > An analogy perhaps is that whether you get a "permission denied" > error about some target table is not conditional on whether the > query actually attempts to delete any rows from it. We go out > of our way to make sure that that happens when required by spec, > even if the planner is able to prove that no delete will happen. > > None of this is meant to justify throwing an internal error here; > that's clearly bad. I'm just saying that there would be little > wrong with fixing it by throwing "cannot delete" instead. The user > has no right to expect that that won't happen in a case like this. We might be able to throw the "cannot delete from foreign table" like this: @@ -987,6 +987,16 @@ add_row_identity_columns(PlannerInfo *root, Index rtin= dex, fdwroutine =3D GetFdwRoutineForRelation(target_relation, false); + if (fdwroutine->ExecForeignDelete =3D=3D NULL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot delete from foreign table \"%s\"", + RelationGetRelationName(target_relation)))); + if (fdwroutine->ExecForeignUpdate =3D=3D NULL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot update foreign table \"%s\"", + RelationGetRelationName(target_relation)))); if (fdwroutine->AddForeignUpdateTargets !=3D NULL) fdwroutine->AddForeignUpdateTargets(root, rtindex, target_rte, target_relatio= n); but I am not sure how consistent the following is after applying that: postgres=3D# set enable_partition_pruning to off; SET postgres=3D# EXPLAIN verbose DELETE FROM pt WHERE false; ERROR: cannot delete from foreign table "p1" postgres=3D# set enable_partition_pruning to on; SET -- we don't even hit the foreign table in the planner postgres=3D# EXPLAIN verbose DELETE FROM pt WHERE false; QUERY PLAN ------------------------------------------------------- Delete on public.pt (cost=3D0.00..0.00 rows=3D0 width=3D0) -> Result (cost=3D0.00..0.00 rows=3D0 width=3D0) Output: ctid Replaces: Scan on pt One-Time Filter: false (5 rows) --=20 Thanks, Amit Langote