Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nvTx8-0003oR-E1 for pgsql-bugs@arkaria.postgresql.org; Mon, 30 May 2022 01:12:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nvTx5-0005sZ-JS for pgsql-bugs@arkaria.postgresql.org; Mon, 30 May 2022 01:12:11 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nvTx5-0005sP-8g for pgsql-bugs@lists.postgresql.org; Mon, 30 May 2022 01:12:11 +0000 Received: from mail-oi1-x22b.google.com ([2607:f8b0:4864:20::22b]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nvTx2-0007fw-IT for pgsql-bugs@lists.postgresql.org; Mon, 30 May 2022 01:12:10 +0000 Received: by mail-oi1-x22b.google.com with SMTP id r68so12343456oie.12 for ; Sun, 29 May 2022 18:12:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=kdV/ygEHy5DKtcwKjif1eEK89/xk4ibXhq5AKuH75zc=; b=pDR1N7GFEU3t4Dg38zdgJh+7+s1rrnAhAOjK5wsRONe5Nw2iy5quj9eYbrhXnruLV7 mEELleiaRJEfVYLRkE1mPSx59dj8LQY0B3hNe0Q0PZIU1k7qhVYK23ToKLsZBys30OFj 9kwMaR+d6X5B/EpDpswTKb8lVODeMyfiIzUtNIuqf1HHgpn7x7s9ea4LUWjO4ixjjxK5 of7TsPiKgquNd34r0LrQzH5Zt7U6S2YuhRkxii/SNkrIhZ/zkVwFvSqWysDfANmj3NzY NeYqk+2Z3lIDQfFUKbLTxbrKGK2fgf/aGfPVvzfLBRRYzy7Yn+LCrPJcU/dSlr1vPHiB zK+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=kdV/ygEHy5DKtcwKjif1eEK89/xk4ibXhq5AKuH75zc=; b=GzUE2V5e0jQYRu6La3Ev9oiSaOQS348tN9Sx9RCFG1LiHUNyJYKMLU6C0YcS77i56R nmWL+4AOWn4Dg3i5XUFX6fe9/9mo2j7aDUjlxsbjVK3youOHpaCpfDAYrWnwrLMGYtZq ++LTX+qClKTJajZyBnv1FYpbpG1OIpyK4jpA4isFynUlOubMSMaUpUhvpTHe6e/kzMiQ OiAofuzcViZMLRpZhgB/x2kKh7lTc02vGHuboAptMT5fnMJ1c7MBgypGjFvTObps0E74 SWqC0232UdWrUMhCSYCvORZ2c639+6heTXQgROQgKv3rHQKyB55kxV/QqgNEiogHT3Oh X03g== X-Gm-Message-State: AOAM532nG6YZmn+1+GzrzRD3ydy/AaJEV0IxxNxVHkCWIJPhuEkVRApV +w44kRLCGet+ioDx5cIf11VoVofyDrxi4WTOIJ7qIIh/WAs= X-Google-Smtp-Source: ABdhPJwJN+m6ooUHfLBwiEosiF3/p6ri2gwttR03Gr366F9SXjQaqycnhvuXK5qkGdFYa+WuHwTJy7TQw1AtVH036uI= X-Received: by 2002:aca:60d7:0:b0:325:54db:b78e with SMTP id u206-20020aca60d7000000b0032554dbb78emr8374717oib.259.1653873126883; Sun, 29 May 2022 18:12:06 -0700 (PDT) MIME-Version: 1.0 References: <17502-281a7aaacfaa872a@postgresql.org> In-Reply-To: From: David Rowley Date: Mon, 30 May 2022 13:11:53 +1200 Message-ID: Subject: Re: BUG #17502: View based on window functions returns wrong results when queried To: =?UTF-8?Q?Daniel_Farka=C5=A1?= Cc: Magnus Hagander , PostgreSQL mailing lists Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, 30 May 2022 at 10:30, David Rowley wrote: > I'm a little bit uncertain if the correct fix is to have > expression_returns_set() look deeper into WindowFuncs to check if the > WindowClause that the function belongs to has any SRFs in the > PARTITION BY / ORDER BY clause. Unfortunately, doing that means > having to pass the PlannerInfo to expression_returns_set(). I don't > quite see how that could be made to work in the back branches. There does seem to be other weird anomalies as a result of expression_returns_set() not looking for SRFs in the WindowFunc PARTITION BY / ORDER BY clause. Looking at the usage of expression_returns_set() in make_sort_input_target(), I'd have expected the following 2 queries to act in the same way: setup: create table ab (a int, b int); insert into ab values(1,1),(1,2),(2,1),(2,2); postgres=# select distinct on (a) a,b, row_number() over (order by generate_Series(1,2)) from ab order by a,b; a | b | row_number ---+---+------------ 1 | 1 | 1 2 | 1 | 7 (2 rows) postgres=# select distinct on (a) a,b, generate_Series(1,2) from ab order by a,b; a | b | generate_series ---+---+----------------- 1 | 1 | 1 1 | 1 | 2 2 | 1 | 1 2 | 1 | 2 (4 rows) The fact that those are different is starting to make me think that expression_returns_set() should be looking into WindowFuncs to see if the WindowClause has SRFs rather than adding special code to remove_unused_subquery_outputs() in order to fix the bug being reported on this thread. However, I'm not sure the latter of the above two queries result makes any sense given that our documentation [1] claims: "PostgreSQL's behavior for a set-returning function in a query's select list is almost exactly the same as if the set-returning function had been written in a LATERAL FROM-clause item instead. For example," the "almost" is later defined as: "It would be exactly the same, except that in this specific example, the planner could choose to put g on the outside of the nested-loop join, since g has no actual lateral dependency on tab." which only indicates that the order of the results may differ, not the actual results themselves. You can see the LATERAL version only returns 2 rows: postgres=# select distinct on (a) a, b, g.s from ab, lateral generate_Series(1,2) g(s) order by a,b; a | b | s ---+---+--- 1 | 1 | 1 2 | 1 | 1 (2 rows) The following is also pretty strange. Why should adding the SRF column to the ORDER BY change the number of output rows? postgres=# select distinct on (a) a,b, generate_Series(1,2) from ab order by a,b,3 desc; a | b | generate_series ---+---+----------------- 1 | 1 | 2 2 | 1 | 2 (2 rows) postgres=# select distinct on (a) a,b, generate_Series(1,2) from ab order by a,b; a | b | generate_series ---+---+----------------- 1 | 1 | 1 1 | 1 | 2 2 | 1 | 1 2 | 1 | 2 (4 rows) The LATERAL version of this will return 2 rows regardless of what the ORDER BY says: postgres=# select distinct on (a) a, b, g.s from ab, lateral generate_Series(1,2) g(s) order by a,b,g.s DESC; a | b | s ---+---+--- 1 | 1 | 2 2 | 1 | 2 (2 rows) postgres=# select distinct on (a) a, b, g.s from ab, lateral generate_Series(1,2) g(s) order by a,b; a | b | s ---+---+--- 1 | 1 | 1 2 | 1 | 1 (2 rows) In addition to what the documentation claims about SRFs in the target list being the same as LATERAL, maybe the following should give us some guidance on if the non-lateral SRF queries above should return 2 or 4 rows: postgres=# select distinct generate_Series(0,1)/2; ?column? ---------- 0 (1 row) In the above, the ProjectSet occurs before the distinctification. That would translate into the 2-row version of the DISTINCT ON query above being correct. I think that roughly translates into changes being required in both make_sort_input_target() and expression_returns_set(). Does anyone have any other opinions? David [1] https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-SET