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 1vvyJR-00DBOj-2Z for pgsql-hackers@arkaria.postgresql.org; Fri, 27 Feb 2026 13:55:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vvyJP-003dn6-2N for pgsql-hackers@arkaria.postgresql.org; Fri, 27 Feb 2026 13:55:23 +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 1vvyJP-003dmr-1P for pgsql-hackers@lists.postgresql.org; Fri, 27 Feb 2026 13:55:23 +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 1vvyJL-00000001Zsc-0q7E for pgsql-hackers@postgresql.org; Fri, 27 Feb 2026 13:55:22 +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=cP2zdaYw8DPelopRQJlmFNNS8xfEfSObUducVAHfBuQ=; b=Y/k6WW16UnbEu2xwaXxhx0ML3R 5kKQfb+P2dMAGpDh28Kt2DQJLicUfbs98s47y7w3Wh+7d0ej3YrXwb9UpF1e/XJqgSEmr0ghg/yjo N1JfzFJ9RB7IojmrOp7WAlEzNkZ9GEUe7vtlhsAFq9DtFTnW8EQQK4euxGhTE/n6sawsQarU3hAVj GEIQx4qCjZw88Scfdf9jQqCk4wtI1c49fvotBGGJUMscTeXclu9VA9wIYkoVYltHQ1ehZTt8ire1z f8CWcVy5iZQS/sZyQOLTlJVUEGQhBdvhAiVKBSUa7OTqBCxQVifGbpsudyUv146OPQZhDY3NR0+Ga tZRgkqUw==; Received: from [2409:11:4120:300:e6ea:b43a:9c99:615] (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 1vvyJF-003dF1-1g; Fri, 27 Feb 2026 13:55:15 +0000 Date: Fri, 27 Feb 2026 22:54:56 +0900 (JST) Message-Id: <20260227.225456.33226875991025537.ishii@postgresql.org> To: assam258@gmail.com Cc: vik@postgresfriends.org, er@xs4all.nl, jacob.champion@enterprisedb.com, david.g.johnston@gmail.com, peter@eisentraut.org, pgsql-hackers@postgresql.org Subject: Re: Row pattern recognition From: Tatsuo Ishii In-Reply-To: References: <20260224.140927.1828965853586507533.ishii@postgresql.org> <20260224.204417.914253025244188300.ishii@postgresql.org> X-Mailer: Mew version 6.8 on Emacs 29.3 Mime-Version: 1.0 Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit X-Host-Lookup-Failed: Reverse DNS lookup failed for 2409:11:4120:300:e6ea:b43a:9c99:615 (failed) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Henson, > Hi Tatsuo, > > Currently we do not account the cost of RPR while planning. Attached >> is the first attempt to try to estimate the RPR costs. The cost model >> is very simple: >> >> expression cost per PATTERN variable * number of input tuples >> >> Any idea to make this estimation better? >> > > > foreach(lc, windowFuncs) >> { >> ... >> + /* also add DEFINE clause expressions' cost to per-input-row costs */ >> + if (winclause->rpPattern) >> + { >> + List *pattern_vars; /* list of pattern variable names */ >> + ListCell *lc2; >> + >> + pattern_vars = collectPatternVariables(winclause->rpPattern); >> + >> + /* iterate according to the pattern variable */ >> + foreach(lc2, pattern_vars) >> + { >> + char *ptname = strVal((char *) lfirst(lc2)); > > `collectPatternVariables` returns a list of String nodes (via > `makeString()`), so `strVal(lfirst(lc2))` is the idiomatic form. > The `(char *)` cast is misleading. Ok. > There is also a correctness issue: DEFINE expressions belong to the > window clause, not to individual window functions, so their cost > should not be multiplied by the number of window functions sharing > the clause. You are right. > The fix is to compute the DEFINE cost once outside the loop and add > it to `startup_cost` and `total_cost` directly, after the > `foreach(lc, windowFuncs)` block. Looks good. > Regarding the cost model: the NFA executor evaluates all DEFINE > expressions once per row into a shared `nfaVarMatched[]` array that > all active contexts read from, and contexts advance strictly forward > so no prior row is ever re-evaluated. The one-evaluation-per-row > cost model is therefore accurate. NFA-aware cost > modeling could be built on top of this foundation in a separate patch > down the road, once the NFA implementation has matured. > > For now, the DEFINE expression costs themselves already serve as a > natural penalty ― a window clause with RPR will consistently appear > more expensive than a comparable plain window function. This gives > the surrounding plan a reasonable cost signal for decisions such as > join ordering and materialization of RPR subqueries. So the current > approach is reasonable as a first step. > > Other than that, the approach looks good to me. Would it be okay if > I revise the patch along those lines? Yes, no problem. Thanks! -- Tatsuo Ishii SRA OSS K.K. English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp