Re: Row pattern recognition
Henson Choi <assam258@gmail.com>
From: Henson Choi <assam258@gmail.com>
To: ishii@postgresql.org, 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
Date: 2026-07-03T22:22:10Z
Lists: pgsql-hackers
Hi Tatsuo, > In v50-0006-tidy-plumbing.patch, the planner cost model seems slightly > changed. Before the cost was charged according to the number of > pattern variables in PATTERN clause. But now it is charged according > to the number of pattern variables in DEFINE clause. Maybe I missed > the discussion on the changing. Can you please explain the reason of > the change? The change is a simplification that came out of Jian's v48 review, and it does not change the cost the model produces. It follows Jian's suggestion from 2026-06-15 [1]: > collectPatternVariables is not needed. > The parser already ensures every DEFINE variable appears in PATTERN, > so there is nothing to filter. > Also, we don't really do anything special (like make a dummy Const) > regarding PATTERN variables that not appearing in the DEFINE clause. The two loops charge exactly the same set, for the following reason: - The old loop walked the unique PATTERN variables (collectPatternVariables deduplicates, returning each name once) and, for each, looked up the matching DEFINE entry by resname and charged that DEFINE's cost. - Every DEFINE variable is guaranteed to appear in PATTERN -- the parser rejects a DEFINE variable that is not used in PATTERN (errmsg "DEFINE variable \"%s\" is not used in PATTERN" in parse_rpr.c). So the DEFINE clause is always a subset of the unique PATTERN variables, and each DEFINE resname is unique. - A PATTERN variable that has no DEFINE contributes nothing to the old loop, because the inner resname lookup finds no match. So the old loop already charged each DEFINE expression exactly once, and nothing else. Iterating defineClause directly, as v50-0006 does, visits precisely that same set once each. The estimate is unchanged; only the redundant outer walk over PATTERN and the per-variable resname lookup into the DEFINE clause are removed. This also matches the premise of the cost model we settled on back in February: the NFA executor evaluates every DEFINE expression once per row, so the natural unit for the per-tuple charge is the DEFINE variable. [1] https://www.postgresql.org/message-id/CACJufxFAQhbOD9EVCTAy-VwDbG4446N10GsxCcgdpFnjHO1Efw%40mail.gmail.com Best regards, Henson
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Adjust cross-version upgrade tests for seg_out() fix
- 3e3d7875e956 19 (unreleased) cited
-
Rationalize error comments in partition split/merge tests
- ecb2508aaf9b 19 (unreleased) cited
-
Add fast path for foreign key constraint checks
- 2da86c1ef9b5 19 (unreleased) cited
-
Fix assorted pretty-trivial memory leaks in the backend.
- e78d1d6d47dc 19 (unreleased) cited
-
Add temporal FOREIGN KEY contraints
- 89f908a6d0ac 18.0 cited
-
Add trailing commas to enum definitions
- 611806cd726f 17.0 cited
-
Remove obsolete executor cleanup code
- d060e921ea5a 17.0 cited