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 1m7Jwv-0008OD-Nv for pgsql-general@arkaria.postgresql.org; Sat, 24 Jul 2021 15:52:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1m7Jwu-00080O-AC for pgsql-general@arkaria.postgresql.org; Sat, 24 Jul 2021 15:52:24 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m7Jwt-00080F-C6 for pgsql-general@lists.postgresql.org; Sat, 24 Jul 2021 15:52:24 +0000 Received: from mail-mw2nam10olkn2096.outbound.protection.outlook.com ([40.92.42.96] helo=NAM10-MW2-obe.outbound.protection.outlook.com) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m7Jwo-0005Z0-4G for pgsql-general@postgresql.org; Sat, 24 Jul 2021 15:52:22 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=E/IEzZitmgfTLGgAybXyiYgp1yt8o1t7W9iqNK8RtZksFwhekQPwrLI8DXBy9dw6szZXiuu4AIaQh+n1LPlEFnYi9VmYp7lqrZR5aljmMAryen2hPcVDT3HePdMdSTZ4WTzvhIMLViGdwDhbaDHKHk1H31hx0Xsrk/WR9djgUOflycMq899LSo76ZLO+1RmHPqgWBeOyh/o06o0xrjvScqYPXgznr+yshznw+Jjy6RVP0i7Ca20jUMQV8gMvTw8IXrT+Bp7+SnCGujMSyQSf70esAR0dkTvmyrrj7lDtNmuKcxO8Ncue2vODYJgUng1I0EeU8YNHfzaJoqIFRa+C1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=z67egzIqjC2700oLQPi+Pne7CKULpfe7c6VIqVJGv08=; b=K0g1pKeohcbNs1r28s7PA0D1ywYRF6IU2GEfxK5CvMn/C84Ze1fGVTsUlKbgZZ4Yu7uH08va/ddvSIwadZhcGbh3EAKm9iMPeu5oEB8oOoZ3LSGNYD466X6ILZxyS1WJbc0c2Svcr2zjqKEwzAn/eAxBuqnm/Y+m1SJOviYuNj9I2Bb71hlaEox5Mueu2BQkMihBX2bmgaanqCHdMStp+YFMqlBwyrsh8RF9v2AfEEodN6s33T291Iouf3egQYLfkt1I1ROwUY0xSl49P+hAkgg2z1PDpwiikHhZvL4GaarKwVczt8t4QKuMpea/gcJjZAO4vh0S3/CpQEU5x/ZiIw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=z67egzIqjC2700oLQPi+Pne7CKULpfe7c6VIqVJGv08=; b=jd8Sv8qYWS8QoeNMJSoY52OVYV3Bm8Jiz3c5ZYOr4ifaXnOOUaHghZPIoZlaLoX5wIh4Yuwo6oeV+wqKK8JSkFUPerl36gZi4PSxvT1K5QyZqMaKbB7V45rzT3u+cLdzr9wRDjIRFN7UPgiJTHT/QIhGcciusxcJKp3LtbWUXcEqBSvE3SLnqExW3WbBW0M6HdgzPuh4Q3HH1ufz4faMIe/uAen22Zl20fhrKSIi6Ac1G582XcRh2m2yg5WGK60W0dfnw4/QLMxDfSLyhQ+auYN1qxk8QdgKE6yOhISmdOBHE8y13GM+XguOVfIC8KD/1SClSiJc+ic5x3GhbWDfyw== Received: from BN7NAM10FT053.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e8f::4c) by BN7NAM10HT169.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e8f::196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.24; Sat, 24 Jul 2021 15:52:15 +0000 Received: from DM5PR06MB3082.namprd06.prod.outlook.com (2a01:111:e400:7e8f::51) by BN7NAM10FT053.mail.protection.outlook.com (2a01:111:e400:7e8f::124) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.24 via Frontend Transport; Sat, 24 Jul 2021 15:52:15 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:E3B30C7897A973A1B6717A0F8F629A96CD84497737C57D0DD22497D0ED273749;UpperCasedChecksum:1F102DA8BDFB40934FE33951DB31B5D230EE1B77E598B2A42C7992300BCC6271;SizeAsReceived:8624;Count:47 Received: from DM5PR06MB3082.namprd06.prod.outlook.com ([fe80::55a5:849e:8253:3188]) by DM5PR06MB3082.namprd06.prod.outlook.com ([fe80::55a5:849e:8253:3188%6]) with mapi id 15.20.4352.026; Sat, 24 Jul 2021 15:52:15 +0000 Subject: Set-Returning functions in a select list To: pgsql-general@postgresql.org References: <159567011970.625.15282665367468168691@wrigleys.postgresql.org> <673790.1595689577@sss.pgh.pa.us> From: J Lumby Message-ID: Date: Sat, 24 Jul 2021 11:52:23 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.3 In-Reply-To: <673790.1595689577@sss.pgh.pa.us> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-TMN: [mtuGbfPlWNNtZEVtwyWBMqf+YThxJWzt] X-ClientProxiedBy: YT1PR01CA0133.CANPRD01.PROD.OUTLOOK.COM (2603:10b6:b01:2f::12) To DM5PR06MB3082.namprd06.prod.outlook.com (2603:10b6:4:40::10) X-Microsoft-Original-Message-ID: <7c2df8b1-77bb-7a4c-ad10-afecaea92618@hotmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from macrch.localdomain (69.165.169.141) by YT1PR01CA0133.CANPRD01.PROD.OUTLOOK.COM (2603:10b6:b01:2f::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.25 via Frontend Transport; Sat, 24 Jul 2021 15:52:14 +0000 X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 47 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 7d018b27-89a8-41e3-ce03-08d94ebb01e1 X-MS-TrafficTypeDiagnostic: BN7NAM10HT169: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: IE1522ul1rTELItEMjCsomGN66dYguxmGtEr2VtHqeoW+Y5CDNfT+tpJvadfRunj7tM/QKxcPhNpm5J8lsqKNg33JteQQ8eKI7GRzWvhqnoHsJC7yitgvLjH/EfT9zM3I095QCEnsnGZTCJP1+if1SIU1o+VAUPNWNSOqbaFXBkPhtrlRPcgltNRlfGYmIWvch7uSYuj5pD7Ud8rzOVt0Xz1AdWvH0tUCjVWO8PiIFZ/FcI8bSFPig/YKgfyc3ga0mz1srcSU+QyTUsu+J+CijZxD+b+CHzbviT1HRbcmA1jENg0qmkXYTOd5WYdwVcKIXyzqPdV0SS9651hdd1yp6G0YzfQwQSeNfaunsVTNa/3soE7pFrHWWGuagdgcyy2T4fC6ybdyk8T4Q+c5j+XftWuiZfwLRVJ9hxx5+6wRb12ffBHXvqxaBmRb3h3PrUU X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ZzBr3hHNM/dQpEG6G37doBJ10v9Uvdde/a1nIWWnq9GVu3zX/2ENCzRSAlPFywJt21Xdcrs5AnekQbUAc3fQoNIwPuQPO8LNV4/53mNCeVue95FUcZ5yDUa3/9Dr4DhGjTebvmU9OVm9qKgwFs2wkQ== X-OriginatorOrg: hotmail.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7d018b27-89a8-41e3-ce03-08d94ebb01e1 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jul 2021 15:52:15.4947 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: BN7NAM10FT053.eop-nam10.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7NAM10HT169 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk I am unclear about the rules which postgresql uses in building a result set when the select list ( see note ) contains several different Set-Returning functions,  possibly with sets of different sizes. At a very high level,   what I see happening is that each Set-Returning expression causes the result set to be expanded with additional rows,  one per member of the set. When there is only one such expression,     this is clear  -   the size of the final result set is N times the size of the output of the final operator where N is the size of the set   (i.e. N times the size if that expression had been a scalar). But it becomes unclear where there is more than one such expression. I can't find much on this point in the doc  (I am looking in PostgreSQL 13.2 Documentation).    There is one small example in "9.25. Set Returning Functions" but in this example there is only one Set-Returning expression in the select list. Also the description of the SELECT command mentions something called a "row group" : "The actual output rows are computed using the SELECT output expressions for each selected row or row group. (See SELECT List below.)" but no mention of Set-Returning expressions in the referenced section. I tried an experiment : echo -e "DROP SCHEMA testing cascade; CREATE SCHEMA testing; CREATE TABLE testing.set_returning_in_select_list (id int4 , bitmask_a int , bitmask_b int ); insert into testing.set_returning_in_select_list values ( 1 , x'1010'::int , x'0101'::int ) , ( 2 , x'2020'::int , x'0202'::int ) , ( 3 , x'3030'::int , x'0303'::int ); select id , to_hex(bitmask_a) as hex_a , unnest( array [ ( bitmask_a & 16 ) ,  ( bitmask_a & 32 ) , ( bitmask_a & 48 ) ] ) as bits_of_a ,                to_hex(bitmask_b) as hex_b from testing.set_returning_in_select_list order by bits_of_a; select id , to_hex(bitmask_a) as hex_a , unnest( array [ ( bitmask_a & 16 ) ,  ( bitmask_a & 32 ) , ( bitmask_a & 48 ) ] ) as bits_of_a ,                to_hex(bitmask_b) as hex_b , unnest( array [ ( bitmask_b & 1 ) ,  ( bitmask_b & 2 ) , ( bitmask_b & 3 ) ] ) as bits_of_b  from testing.set_returning_in_select_list order by bits_of_a; select id , to_hex(bitmask_a) as hex_a , unnest( array [ ( bitmask_a & 16 ) ,  ( bitmask_a & 32 ) , ( bitmask_a & 48 ) ] ) as bits_of_a ,                to_hex(bitmask_b) as hex_b , unnest( array [ ( bitmask_b & 3 ) ,  ( bitmask_b & 2 ) , ( bitmask_b & 1 ) ] ) as bits_of_b ,                unnest( array [ ( bitmask_b & 3 ) ,  ( bitmask_b & 2 ) , ( bitmask_b & 1 ) , ( bitmask_b & 17 ) ] ) as extraneous_bits_of_b  from testing.set_returning_in_select_list order by bits_of_a;" | psql -e The output of the last query is,  firstly,  different on postgresql-9.6 than on 13.3,   and secondly,     hard to explain in either case. my outputs appended below. I *think* :  . postgresql-9.6 applies a kind of triple cartesian join on the elements of each set, joining one set with the other set and then again with itself,   ending up with many duplicates  . postgresql-13.3 applies a kind of null-padding extension of the elements of the smaller set and then an arbitrary linear pairing of the two sets,   ending up with one duplicate. Which one,  if any,  is correct?    And why? (note : I am not asking about the case of Set-Returning functions in the FROM clause,  where things seem clear(er).) Cheers,   John Lumby My outputs of the final query :  . postgresql-9.6  id | hex_a | bits_of_a | hex_b | bits_of_b | extraneous_bits_of_b ----+-------+-----------+-------+-----------+----------------------   1 | 1010  |         0 | 101   |         0 |                    0   1 | 1010  |         0 | 101   |         0 |                    1   1 | 1010  |         0 | 101   |         0 |                    1   1 | 1010  |         0 | 101   |         0 |                    1   2 | 2020  |         0 | 202   |         2 |                    2   2 | 2020  |         0 | 202   |         2 |                    2   2 | 2020  |         0 | 202   |         2 |                    0   2 | 2020  |         0 | 202   |         2 |                    0   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    0   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    0   1 | 1010  |        16 | 101   |         1 |                    1   3 | 3030  |        16 | 303   |         3 |                    3   3 | 3030  |        16 | 303   |         3 |                    1   3 | 3030  |        16 | 303   |         3 |                    1   3 | 3030  |        16 | 303   |         3 |                    2   2 | 2020  |        32 | 202   |         2 |                    0   2 | 2020  |        32 | 202   |         2 |                    2   2 | 2020  |        32 | 202   |         2 |                    0   2 | 2020  |        32 | 202   |         0 |                    0   2 | 2020  |        32 | 202   |         2 |                    2   2 | 2020  |        32 | 202   |         0 |                    2   2 | 2020  |        32 | 202   |         0 |                    0   2 | 2020  |        32 | 202   |         0 |                    2   3 | 3030  |        32 | 303   |         2 |                    2   3 | 3030  |        32 | 303   |         2 |                    3   3 | 3030  |        32 | 303   |         2 |                    1   3 | 3030  |        32 | 303   |         2 |                    1   3 | 3030  |        48 | 303   |         1 |                    3   3 | 3030  |        48 | 303   |         1 |                    2   3 | 3030  |        48 | 303   |         1 |                    1   3 | 3030  |        48 | 303   |         1 |                    1 (36 rows)  . postgresql-13.3  id | hex_a | bits_of_a | hex_b | bits_of_b | extraneous_bits_of_b ----+-------+-----------+-------+-----------+----------------------   1 | 1010  |         0 | 101   |         0 |                    0   2 | 2020  |         0 | 202   |         2 |                    2   1 | 1010  |        16 | 101   |         1 |                    1   1 | 1010  |        16 | 101   |         1 |                    1   3 | 3030  |        16 | 303   |         3 |                    3   2 | 2020  |        32 | 202   |         0 |                    0   2 | 2020  |        32 | 202   |         2 |                    2   3 | 3030  |        32 | 303   |         2 |                    2   3 | 3030  |        48 | 303   |         1 |                    1   1 | 1010  |           | 101   |           |                    1   3 | 3030  |           | 303   |           |                    1   2 | 2020  |           | 202   |           |                    0 (12 rows)