Re: Row pattern recognition

Henson Choi <assam258@gmail.com>

From: Henson Choi <assam258@gmail.com>
To: Tatsuo Ishii <ishii@postgresql.org>
Cc: 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, pgsql-hackers@postgresql.org
Date: 2026-03-21T12:42:52Z
Lists: pgsql-hackers
Hi Tatsuo,

>   0004: Fix window_last_value set_mark during RPR
> >         Restore set_mark=true in window_last_value (normal behavior)
> >         and add an RPR-specific override inside WinGetFuncArgInFrame.
> >         This keeps the RPR workaround localized rather than changing
> >         the caller's semantics unconditionally.
>
> So, if RPR is active, WinSetMarkPosition() is not called at all?  That
> seems too strong limitation.  Can't we set mark at frameheadpos even
> if RPR is active? It seems safe since the only allowed franme start
> option is ROWS BETWEEN CURRENT ROW and we never step back to the rows
> before frameheadpos.


You raise a valid point. Setting mark at frameheadpos would be safe
for the window function's own read pointer, since we only allow
ROWS BETWEEN CURRENT ROW.

However, the difficulty is with the PREV/NEXT navigation. In the
experimental patch, PREV accepts an optional offset argument --
e.g. PREV(price, N) -- and this offset can be a runtime expression
whose value is not known until evaluation time. If the mark is
advanced to frameheadpos, PREV(price, N) with a large N could try
to access rows that the tuplestore has already truncated.

This is why the experimental patch takes a different approach: it
creates a separate nav_winobj with its own mark pointer pinned at
position 0, so that the tuplestore never truncates rows that PREV
might need. The window function's own mark management is left
unchanged.

The mark=0 approach is safe but conservative -- it prevents the
tuplestore from releasing any rows within the partition. The SQL
standard (ISO/IEC 19075-5, Subclause 5.6.2) requires the offset
argument to be a "runtime constant" -- meaning it cannot reference
columns or row pattern variables. So in practice, the maximum
offset is always known at plan time, which opens the door for a
future optimization: advance the mark to (currentpos - max_offset)
when all PREV offsets in the DEFINE clause are constant.

Since the experimental patch redesigns how mark works for PREV/NEXT
navigation, I think we should drop 0004 from the current series
and revisit the set_mark question together with the experimental
patch. What do you think?

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 →
  1. Adjust cross-version upgrade tests for seg_out() fix

  2. Rationalize error comments in partition split/merge tests

  3. Add fast path for foreign key constraint checks

  4. Fix assorted pretty-trivial memory leaks in the backend.

  5. Add temporal FOREIGN KEY contraints

  6. Add trailing commas to enum definitions

  7. Remove obsolete executor cleanup code