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 1w7bo3-005WTr-1R for pgsql-bugs@arkaria.postgresql.org; Tue, 31 Mar 2026 16:19:07 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w7bo1-00BIpY-0J for pgsql-bugs@arkaria.postgresql.org; Tue, 31 Mar 2026 16:19:05 +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.96) (envelope-from ) id 1w7bVw-00B8TV-1I for pgsql-bugs@lists.postgresql.org; Tue, 31 Mar 2026 16:00:24 +0000 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w7bVu-00000001zYX-2nm6 for pgsql-bugs@lists.postgresql.org; Tue, 31 Mar 2026 16:00:23 +0000 Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-66ad907833dso10189083a12.3 for ; Tue, 31 Mar 2026 09:00:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774972821; cv=none; d=google.com; s=arc-20240605; b=JwVRu1K6tCZntsjYp44zDl4GdtQYxKp2icTZMJIaHPrxFywn21jKR9wHy2mWxW4bUx Rq/U9FXjoHphGeqjzbQJzCsj6IHkYEgHzE1BqwPOLOjr8sqHx71QqQ3hyTW5Zg+ZTceS RfsxUDEVn5si58SVmx5tqu6qRjxDHeC6f7woBlbu2JTq7wRy9JBThm5x57uFTcHbEYbz +xIcDLZwx94AUndx4z5VyIzpA0N3PiCMEwESgVkcV8/QrNvZN+HP3bD7a7Kes+23LSlJ LhWruxsTw1L5Cus8RhlWbCh/R+F5qdSd19ay0iEsks1Oh6NfNQL2axv2hgTNCVyZjiF4 h79w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=Lord53HqEoLZNouSzj/aafhsNU7B0YBwVUmQN39vEr0=; fh=YqCCkVLAZ9VDEjvsG9Tbe4cNXxRW+cbqV0aVtnNWw+k=; b=HQwO15stZShQzt19q2L8xiHEJry5nIYyFJHsPf2Sl7whC1s+kXeYT6GVRjZyfECvs4 vMJz0xjVz3W+VEX+txcNgcstAD8JtNBBgxjV2RePLF3E8ABbvvbruLUvgrQEO4Jqq8I8 81w/LbtlCB7l2+9BhHAJNnBt4nR+n8eHnVgQicp1iwY/j/tgvMB2h8/nkG2UqUSfYa0y Y5MXZ/cYNQVBOPfsjyyCBA+rwma/hgC2614CKy9+V/ozEQK5TCkxRzEMrit5TJ/Ql/oh e4EbfV77f6cILDv/YJPCIy4X00xI76XWjT9tKA6kjA9Tc0VACDs4EnF1sjNDSbRqasfs Y6zw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774972821; x=1775577621; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Lord53HqEoLZNouSzj/aafhsNU7B0YBwVUmQN39vEr0=; b=ecXk0v6npRl2FMrnfOtpAGNs6CeNmwRAETFMHeiVBZ3rLohGTvihDpNFfyVfdobq3Y mB69JutYpaC3mgO1CUJ0b8EwJCvpCKG2dGW/7umnyRj28qgroC2CAe67z5BzwCSpq6WS u7FoiboWAnH1b0l9QeHiF73n2DlXzjgwRGg7l7623cF4tTTW2wsDfhsfybRdTJQ8ktGG cunRVcKuXL4+f/v1gTjXGxZSfKPm48KLW/N3Fqty0OF9qWTz0iWrEyeczNHCKN/vGJTC eVuegFe/UIzRHrR+Er6jkpwqkfPf8vxUZ4o/ExhKK5qehmQE3fMV0aUL0RyifJSHDX9j ye5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774972821; x=1775577621; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Lord53HqEoLZNouSzj/aafhsNU7B0YBwVUmQN39vEr0=; b=R9/rov98uXeLASEPeURDjayAtQ8dKM5xRODjKJy1hHD8N/KdmxE67/Feb2XlLcx6sw qhQ6ErswqW1V87QhE20nBX/Zx8M7HP1BK3X6i0/S+9lj8mw9aKE4y2FVpRhMViOlDUX9 J503/s+d0KzvLAytKSZOLt8nXi+0kGo2ftC9FsdZGI88wZJGbbP8Joeso4biyfnHWuZ/ VPmTLQRHB7fTokeANlISPQ6W4buEP+QpBucta22Hvc9HEsrz5o6GAJZVKiTM4xUaV3i/ st/lyNV10Z88f1EGADnbpgdQKX10c8W3rMntle6IeeS+7NAoIi5cZqQgtQFG7s72FPrA XydA== X-Gm-Message-State: AOJu0Ywqs0PxoWvgvD5529z+y09UZsxigqHCW4V2FRLkIMnqP+LecPFs H/TFdiiXQJDOZZcMzI6fIAZZgOAfMWLI2WkyRTKHW5e4kI4zmsHm0bqDQp55oD1QgUli1HZQ9gH ayfmOWvq0XafcHXfTc0I3lkreXob7yYI= X-Gm-Gg: ATEYQzyaE0Ap2Do8USFnxuHGov7NR9FELuV/q6HbGXf7+Ij+fFTy+woRQHbymiKT3xQ 5elKRaUZENK0iCFaL+deWj6wa/Gi9ogs1RQFtmSFED8I2c+40yS0vKeKDdspAv5b+v4mZVVKtS2 3c1SDLNOObYsXcKTXDNV8qz7xfpCj2JU/RCQamIHmeKvLDAxpea0kBL25V/qaKPU98clnWsGiw6 oNfgjTeqGeJMw31jBO0emvyl/felPq4oGr2hcjKEVHPmtt9Vcr4THEyo8/NbQHDHD9wx8fmwBcm wJEWxFA= X-Received: by 2002:a05:6402:2706:b0:66b:eb1d:b22a with SMTP id 4fb4d7f45d1cf-66db0cf8c93mr22330a12.26.1774972820970; Tue, 31 Mar 2026 09:00:20 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Justin Christensen Date: Tue, 31 Mar 2026 11:00:09 -0500 X-Gm-Features: AQROBzCRkQ9c_lfgTMo2SOf3UDcwhAyd7bocVCBSMzVItIMWJf5yNYdZSJc8OUM Message-ID: Subject: Re: Surprising behavior with pushing predicates down into a view To: David Rowley Cc: pgsql-bugs@lists.postgresql.org Content-Type: multipart/alternative; boundary="0000000000007ae1e7064e541058" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000007ae1e7064e541058 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Ah. I did happen to skim the postgres source and I did see that subplans were being rejected in qual_is_pushdown_safe before I sent this over, and I noticed a few comments that made it seem like that was a design choice at the time that could stand to be revisited later: "XXX that could stand to be reconsidered, now that we use Paths." Is this a potentially desirable enhancement for it to work the way I expected or is it an explicit design choice for it to remain as-is? Correct me if I'm wrong, but it theoretically could be pushed down into the sub query without affecting correctness, and it's just a question of effort and query planning efficiency? Are we just saying the juice is not worth the squeeze and making this change could affect stability? On Tue, Mar 31, 2026 at 7:44=E2=80=AFAM David Rowley = wrote: > On Tue, 31 Mar 2026 at 22:45, Justin Christensen > wrote: > > When I query this view using a simple constant ticker like 'AAPL' the > query plan shows that it correctly filters the set of tickers before > applying the return calculations, joining, and then calculating beta. I'v= e > included the EXPLAIN output after the query in this gist. > > > > > https://gist.github.com/JustinChristensen/1cad256ea61ad30aa39d42aebc4557b= 9#file-literal-filter-sql > > > > When I query this view using a subquery to find the tickers to filter o= n > it instead tries to execute the view and calculate the beta for all of th= e > tickers in the table before filtering: > > In short, this isn't a bug. > > When planning subqueries, which is effectively how a VIEW will be > planned unless it passed is_simple_subquery()'s tests, we only > consider pushing down "base" quals into that subquery. When you do > ticker =3D 'AAPL', that's a base qual, and that can be pushed down > because ticker is in the WINDOW's PARTITION BY clause, but ticker IN > (SELECT ticker FROM metrics ORDER BY random() LIMIT 50) is converted > into a SEMI join much earlier in planning, so that isn't a base qual > anymore. Even if we didn't do that tranformation in > convert_ANY_sublink_to_join(), we'd still fail to push down the base > qual into the subquery as qual_is_pushdown_safe() doesn't accept base > quals with subplans. > > You might be better off changing the view to a table returning > function which accepts a ticker parameter and calling that function > once for each ticker you need. > > David > --0000000000007ae1e7064e541058 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Ah. I did happen to skim the postgres source and I di= d see that subplans were being rejected in qual_is_pushdown_safe before I s= ent this over, and I noticed a few comments that made it seem like that was= a design choice at the time that could stand to be revisited later: "= XXX that could stand to be reconsidered, now that we use Paths."
Is this a potentially desirable enhancement for it to work the way = I expected or is it an explicit design choice for it to remain as-is? Corre= ct me if I'm wrong, but it theoretically could be pushed down into the = sub query without affecting correctness, and it's just a question of ef= fort and query planning efficiency? Are we just saying the juice is not wor= th the squeeze and making this change could affect stability?

On Tue, Mar 31, 2026 at 7:44=E2=80=AFAM David Rowley <dgrowleyml@gmail.com> wrote:
=
On Tue, 31 Mar 2026 at 22= :45, Justin Christensen
<jus= tin.christensen89@gmail.com> wrote:
> When I query this view using a simple constant ticker like 'AAPL&#= 39; the query plan shows that it correctly filters the set of tickers befor= e applying the return calculations, joining, and then calculating beta. I&#= 39;ve included the EXPLAIN output after the query in this gist.
>
> https://gist.github.com/JustinChristensen/1cad256ea61ad30aa39d42aebc4557= b9#file-literal-filter-sql
>
> When I query this view using a subquery to find the tickers to filter = on it instead tries to execute the view and calculate the beta for all of t= he tickers in the table before filtering:

In short, this isn't a bug.

When planning subqueries, which is effectively how a VIEW will be
planned unless it passed is_simple_subquery()'s tests, we only
consider pushing down "base" quals into that subquery. When you d= o
ticker =3D 'AAPL', that's a base qual, and that can be pushed d= own
because ticker is in the WINDOW's PARTITION BY clause, but ticker IN (SELECT ticker FROM metrics ORDER BY random() LIMIT 50) is converted
into a SEMI join much earlier in planning, so that isn't a base qual anymore. Even if we didn't do that tranformation in
convert_ANY_sublink_to_join(), we'd still fail to push down the base qual into the subquery as qual_is_pushdown_safe() doesn't accept base quals with subplans.

You might be better off changing the view to a table returning
function which accepts a ticker parameter and calling that function
once for each ticker you need.

David
--0000000000007ae1e7064e541058--