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 1teuu7-00GMMp-S8 for pgsql-hackers@arkaria.postgresql.org; Mon, 03 Feb 2025 11:46:16 +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 1teuu6-00CnL3-Rx for pgsql-hackers@arkaria.postgresql.org; Mon, 03 Feb 2025 11:46:14 +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.94.2) (envelope-from ) id 1teuu6-00CnKu-8r for pgsql-hackers@lists.postgresql.org; Mon, 03 Feb 2025 11:46:14 +0000 Received: from meldrar.postgresql.org ([2a02:c0:301:0:ffff::31]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1teuu3-0031hh-1J for pgsql-hackers@postgresql.org; Mon, 03 Feb 2025 11:46:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Content-Transfer-Encoding:Content-Type: Mime-Version:References:In-Reply-To:From:Subject:Cc:To:Message-Id:Date:Sender :Reply-To:Content-ID:Content-Description; bh=PLDufFAlxM7ZgtumsnpJVZOFFauqPQfHtoo886nTBFY=; b=O/2QSy/v742dtHa015JIeLfn60 8qASI/WIqi9Z5nT7g2VRL5DPMT5/DBtDmZomd/iak5DHly69G9/wgSqCYnd0qqTs6f/pv114tkniD iGrazXj9cnZU46uzWTHCp6jIJ/2Cz+TsY+wP7xAhTpF89kbXHZX9Pawhy7/qIqP/U3zJhIAkPdnjk TRzV6/Q7/zFB0nd16Da/4LU3S2xzJ+gABqURzrxbgPHCNGNxh6YFdd7AiT7VlETFLJwa/HCqeBT2o 8u540x4+hWj/ct/AUWWYoPRMwaGBPJJjz/an2paZF4hR2f/fiFBinPHzy559Pjtdp/TwMAuhKisrI pPlrv6nw==; Received: from [2409:11:4120:300:c6d0:622f:ce05:cbdb] (helo=localhost) by meldrar.postgresql.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.94.2) (envelope-from ) id 1teutz-0017ah-DV; Mon, 03 Feb 2025 11:46:10 +0000 Date: Mon, 03 Feb 2025 20:45:55 +0900 (JST) Message-Id: <20250203.204555.1527524827386762643.ishii@postgresql.org> To: ojford@gmail.com Cc: krasiyan@gmail.com, tgl@sss.pgh.pa.us, vik@postgresfriends.org, pgsql-hackers@postgresql.org, andrew@tao11.riddles.org.uk, david@fetter.org Subject: Re: Add RESPECT/IGNORE NULLS and FROM FIRST/LAST options From: Tatsuo Ishii In-Reply-To: References: <20250128.180232.1596242435813112534.ishii@postgresql.org> X-Mailer: Mew version 6.8 on Emacs 26.3 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Host-Lookup-Failed: Reverse DNS lookup failed for 2409:11:4120:300:c6d0:622f:ce05:cbdb (failed) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > I've looked at it again and I think the code is correct, but I > miswrote that the array needs to be sorted. The above query returns: > x | y | nth_value > ---+---+----------- > 1 | 1 | 2 > 2 | 2 | 1 > 3 | | 2 > 4 | 4 | > 5 | | 4 > 6 | 6 | 7 > 7 | 7 | 6 > (7 rows) > > This is correct, for values of x: > > 1: The first non-null value of y is at position 0, however we have > EXCLUDE CURRENT ROW so it picks the next non-null value at position 1 > and stores it in the array, returning 2. > 2: We can now take the first non-null value of y at position 0 and > store it in the array, returning 1. > 3. We take 1 preceding, using the position stored in the array, returning 2. > 4. 1 preceding and 1 following are both null, and we exclude the > current row, so returning null. > 5. 1 preceding is at position 3, store it in the array, returning 4. > 6. 1 preceding is null and we exclude the current row, so store > position 6 in the array, returning 7. > 7. 1 preceding is at position 5, store it in the array and return 6. > > It will be unordered when the EXCLUDE clause is used but the code > should handle this correctly. I ran this query (not using IGNORE NULLS) and get a result. SELECT x, nth_value(x,2) OVER w FROM generate_series(1,5) g(x) WINDOW w AS (ORDER BY x ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE CURRENT ROW); x | nth_value ---+----------- 1 | 3 2 | 3 3 | 2 4 | 3 5 | 4 (5 rows) Since there's no NULL in x column, I expected the same result using IGNORE NULLS, but it was not: SELECT x, nth_value(x,2) IGNORE NULLS OVER w FROM generate_series(1,5) g(x) WINDOW w AS (ORDER BY x ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE CURRENT ROW); x | nth_value ---+----------- 1 | 3 2 | 4 3 | 4 4 | 3 5 | 4 (5 rows) I suspect the difference is in the code path of ignorenulls_getfuncarginframe and the code path in WinGetFuncArgInFrame, which takes care of EXCLUDE like this. case FRAMEOPTION_EXCLUDE_CURRENT_ROW: if (abs_pos >= winstate->currentpos && winstate->currentpos >= winstate->frameheadpos) abs_pos++; Best reagards, -- Tatsuo Ishii SRA OSS K.K. English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp