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 1wgcPl-006IEK-2e for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Jul 2026 06:02:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wgcPk-00F8Hl-13 for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Jul 2026 06:02:44 +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 1wgcPk-00F8Hc-07 for pgsql-hackers@lists.postgresql.org; Mon, 06 Jul 2026 06:02:44 +0000 Received: from meldrar.postgresql.org ([2a02:c0:301:0:ffff::31]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wgcPh-00000001lNe-3lam for pgsql-hackers@postgresql.org; Mon, 06 Jul 2026 06:02:43 +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=Obe1VeAIoK4bUawLi/uCuKRC7OEedZ3egk39QQcbRS0=; b=ANiTGbwkGsIRx7wnqrGpuRbts7 5jkD2FG7pmW0o6Z6C3smHNM+1fgVWqTVuqB2XaQZ4yGTrK4dynWCbazCuF1jljYjVeATOCLoQBcp3 10JJRJcHQB4eQqcR6y22y6vrpvyVNQs/mjH7Uq8e9lfsxObian9RA9JzeP2pJmUzqgOwwYVJVKKRd x2pNv1VPJDy2wGkYFHYk+dgobsFE6M1L3lQeW1RHQLyVfdZLdRHS03p/h00g9/3O+raZu+m8xCkoy 6FsML915Z/fDxoPtMX1l7hpx1pZn6HbjNz0I6gK9GVzfFy1+tnn/EVhyEqTzMRX/Qqv6ylc4fgGft 6MoL1uGw==; Received: from [2409:11:4120:300:8d9e:2d9a:26d3:cad] (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 1wgcPe-00AnZ6-0l; Mon, 06 Jul 2026 06:02:40 +0000 Date: Mon, 06 Jul 2026 15:02:21 +0900 (JST) Message-Id: <20260706.150221.1117486145015185971.ishii@postgresql.org> To: assam258@gmail.com Cc: jian.universality@gmail.com, 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: References: <20260704.162841.39857602849942465.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:8d9e:2d9a:26d3:cad (failed) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Henson, > In those cases the model is still correct, for a slightly different > reason than the (A|A) rewrite: the executor evaluates each DEFINE > predicate once per row, not once per PATTERN occurrence. For each > row it evaluates every DEFINE once and keeps the boolean results in > a varMatched array. > > When the same A appears at several positions in the pattern -- for > example the A in each branch of (A B | A C), which are distinct > states -- each looks up varMatched[A], so the same entry is read > more than once; but that read reuses the already-computed value, not > a re-evaluation. So repetition in PATTERN never multiplies DEFINE > evaluations, and charging once per DEFINE variable in the cost model > matches what the executor actually does. > > The related question that does run the other way is that today we > evaluate every DEFINE for a row eagerly, not just the ones that row > actually needs. For example, in PATTERN (A B C D) a single match > walks the sequence one variable per row -- each row only needs to > test the single variable its state expects -- yet we still evaluate > A, B, C, and D at every row. > > That is the short-circuit / lazy DEFINE evaluation Jian raised on > 2026-05-26 using that very (A B C D) example (evaluate a predicate > only the first time a state tests it). If we ever adopt it, the > cost model's premise -- every DEFINE once per row -- would change > with it, so the two are tied together. > > There's also a soundness angle that argues for keeping it separate. > DEFINE already forbids volatile functions and sequence operations > (nextval), so the obvious non-deterministic cases are out. The > wrinkle lazy evaluation adds is that a predicate would then be > evaluated zero or one times per row -- skipped whenever no state > reaches it -- rather than always. Whether that is safe for a > predicate carrying some state-affecting behavior the volatility ban > does not exclude is something I haven't worked through, so it wasn't a > call I'd want to make lightly under the current review. > > As we discussed, that one is best left as a separate series after > the initial commit, and since it was Jian's idea I'd be glad to see > him drive it. For now I'd keep it out of the in-flight review so the > commit stays small. Agreed. Regards, -- Tatsuo Ishii SRA OSS K.K. English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp