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 1wettc-0057B8-2e for pgsql-hackers@arkaria.postgresql.org; Wed, 01 Jul 2026 12:18:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wettb-00Dd5m-2L for pgsql-hackers@arkaria.postgresql.org; Wed, 01 Jul 2026 12:18:27 +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.96) (envelope-from ) id 1wettb-00Dd5e-1O for pgsql-hackers@lists.postgresql.org; Wed, 01 Jul 2026 12:18:27 +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.98.2) (envelope-from ) id 1wettY-00000001BwH-3i9s for pgsql-hackers@postgresql.org; Wed, 01 Jul 2026 12:18:27 +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=E6CCX1YUgc7LUSJ+k0JalzGaC11EMO8Cq1KjCGWWzWI=; b=M1nsBdnP2jT8CAdX85RUr69JUB TmxgmLMlz0glEynC8+9NTFSNKBozDcjVHnCb1gGUyvr21OYtn/hDqDjsIWNrFVL45rF5lBw0AJD/c Y3Q9P+bBaNIvYMDLtVjmiNUkYPvmXTUFMHZMCd1LFsr7J1fJoYSyX1q1k3bwpFe3dMFVmSJUT9FMF SYOPsoivQFQMOchUM2396cSBFb7BcZ3Drfvic31N/sVImeAtp7jCtmdnGTgFdEFytg2l/kbNJaLVo i0g6QSn862867ODTUttdCuzHiIdKfENs9mWrj8g2cP8LQiIBpdelCxHweWwLIUZe1Xt8OWujiVVeG naz2qo4w==; Received: from [2409:11:4120:300:10c5:92c3:c8e6:c5fa] (helo=localhost) by meldrar.postgresql.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wettU-008ctM-0u; Wed, 01 Jul 2026 12:18:24 +0000 Date: Wed, 01 Jul 2026 21:18:05 +0900 (JST) Message-Id: <20260701.211805.2273383346456030984.ishii@postgresql.org> To: assam258@gmail.com, jian.universality@gmail.com Cc: pgsql-hackers@postgresql.org, zsolt.parragi@percona.com, sjjang112233@gmail.com, vik@postgresfriends.org, er@xs4all.nl, jacob.champion@enterprisedb.com, david.g.johnston@gmail.com, peter@eisentraut.org, li.evan.chao@gmail.com Subject: Re: Row pattern recognition From: Tatsuo Ishii In-Reply-To: <20260629.183730.1799088184925453299.ishii@postgresql.org> References: <20260622.215536.1729984032454200237.ishii@postgresql.org> <20260629.183730.1799088184925453299.ishii@postgresql.org> X-Mailer: Mew version 6.8 on Emacs 29.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:10c5:92c3:c8e6:c5fa (failed) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > Will continue reviewes tomorrow. Sorry for delay. Here is the review for v50-0005-match-once-per-row.patch. --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -239,6 +239,10 @@ static int64 row_is_in_reduced_frame(WindowObject winobj, int64 pos); static void clear_reduced_frame(WindowAggState *winstate); static int get_reduced_frame_status(WindowAggState *winstate, int64 pos); +static void advance_nav_mark(WindowAggState *winstate, int64 currentPos); +static void advance_reduced_frame_nfa(WindowObject winobj, + RPRNFAContext *targetCtx, int64 pos, + bool hasLimitedFrame, int64 frameOffset); static void update_reduced_frame(WindowObject winobj, int64 pos); /* Forward declarations - NFA row evaluation */ @@ -2521,6 +2525,16 @@ ExecWindowAgg(PlanState *pstate) { if (winstate->rpSkipTo == ST_NEXT_ROW) clear_reduced_frame(winstate); + + /* + * Drive the row pattern match every row, so it tracks the row + * scan rather than frame access: a window function that skips + * the frame (e.g. nth_value() with a NULL offset) must not + * leave the match state behind currentpos. + */ + Assert(winstate->nav_winobj != NULL); + (void) row_is_in_reduced_frame(winstate->nav_winobj, + winstate->currentpos); Is there any reason that we call row_is_in_reduced_frame() here, instead of something like: update_frameheadpos(winstate); update_reduced_frame(winobj, pos); row_is_in_reduced_frame() returns row status. Ignoring it using (void) looks a little bit confusing to me. Regards, -- Tatsuo Ishii SRA OSS K.K. English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp