Hi hackers,

This is the v48 fold previewed in my 2026-05-30 post: the incremental
series carried on top of v47 has been folded back, Jian He's round-3
review [1] is applied (my point-by-point reply [2]), and an in-house
static-analysis pass plus the cosmetic clean-up are now included.

Resolved since the last post:

  D3. AST "absorption" rename -- Tatsuo's call.  Renamed to "merging"
      (nocfbot-0031).

  0025 ereport style (Tatsuo, 2026-06-02) [3]: the single-row frame
  rejection used the old (errcode(...)) wrapping; updated in place to the
  new errcode/errmsg style.  (The remaining RPR ereports are tidied up
  tree-wide in nocfbot-0045.)


Deferred (unchanged):

  D2. RPRContext consolidation (Jian's round-2 #1) -- folded into the
      future R010 infrastructure, where a single context can back both the
      R020 window implementation and R010.  We agreed to defer it at the v47
      stage (Tatsuo, 2026-05-31); it is not part of v48.

Attached: the v47 feature series (v47-0001..0009) rebased onto current
master, plus the full incremental series (nocfbot-0001..0068) carried
on top of it.

Base:

  89eafad297a  2026-06-06  Fix tuple deforming with virtual generated columns

Already posted (nocfbot-0001..0026): 0001..0016 went out in earlier
rounds -- 0001..0011 [4], 0012..0015 [5], and 0016 (sent at the time as
0015) [6]; the 2026-05-30 post [7] renumbered them to run contiguously and
added 0017..0026.  All are rebase only and unchanged, except nocfbot-0025,
whose single-row-frame ereports were updated to the new errcode/errmsg
style (per Tatsuo; see above).  Titles for reference:

  nocfbot-0001  Add DEFINE non-volatile baseline to rpr_integration B9
  nocfbot-0002  Unify RPR DEFINE walkers and reject volatile callees
  nocfbot-0003  Cover RPR empty-match path with EXPLAIN tests; fix stale
                XXX comments
  nocfbot-0004  Reclassify DEFINE qualifier check and reword diagnostic to
                "expression"
  nocfbot-0005  Sync stale comments on DEFINE/PATTERN handling
  nocfbot-0006  Add trailing commas to RPR enum definitions
  nocfbot-0007  Remove optional outer parentheses from ereport() calls in
                RPR files
  nocfbot-0008  Add high-water mark tracking to NFA visited bitmap reset
  nocfbot-0009  Document DEFINE subquery rejection as intentional
                over-rejection
  nocfbot-0010  Remove duplicate #include in nodeWindowAgg.c
  nocfbot-0011  Normalize SQL/RPR standard references
  nocfbot-0012  Add rpr_integration B7 cases for RPR in recursive query
  nocfbot-0013  Reject row pattern recognition in recursive queries
  nocfbot-0014  Enhance README.rpr per Tatsuo Ishii's review
  nocfbot-0015  Round out README.rpr WindowAggState field coverage
  nocfbot-0016  Add raw_expression_tree_walker coverage for RPR raw nodes
  nocfbot-0017  Enhance README.rpr per Jian He's review
  nocfbot-0018  Clarify execRPR.c comments and tighten an Assert
  nocfbot-0019  Change nfa_add_state_unique signature from bool to void
  nocfbot-0020  Add reluctant bounded mid-band test to rpr_nfa
  nocfbot-0021  Define RPR absorption terminology in README.rpr
  nocfbot-0022  Document the get_reduced_frame_status cascade invariant
  nocfbot-0023  Explain the completed-head-context branch in
                update_reduced_frame
  nocfbot-0024  Tighten the RPR frame-boundary check from >= to ==
  nocfbot-0025  Reject single-row window frame in row pattern recognition
  nocfbot-0026  Remove the redundant zero check on the RPR frame ending
                offset

New since the 2026-05-30 post [7] -- nocfbot-0027..0068, in series order.
These apply Jian He's round-3 review [1], an in-house static-analysis
pass, and the v48 cosmetic fold (smallest-first, A..F at the tail).
Patches that change user-visible behavior are tagged [behavior change],
except nocfbot-0042, whose narrow variable-limit change (251 -> 240) is
noted inline.

  nocfbot-0027  Restore findTargetlistEntrySQL99 to static (per Tatsuo)
  nocfbot-0028  Clarify RPR comments
  nocfbot-0029  Rename RPR NFA constructors to make/clone
  nocfbot-0030  Demote RPR nfaVisitedNWords to a local
  nocfbot-0031  Rename the AST-level prefix/suffix rewrite from
                "absorption" to "merging"  (D3)
  nocfbot-0032  Drop non-standard per-group banner labels from RPR
                forward declarations
  nocfbot-0033  Clarify that ExecRPRCleanupDeadContexts always frees the
                failed context
  nocfbot-0034  Correct stale RPR comments and document a defensive
                window check

  nocfbot-0035  Fix unsafe (A{n,})* quantifier flattening
                [behavior change]
      (A{2,})* reaches {0} UNION [2,INF); flattening to A* wrongly admits
      a single A.  Skip multiplication when the outer is skippable and the
      child min >= 2.

  nocfbot-0036  Avoid INF-valued quantifier bound in consecutive-merge
                [behavior change]
      The merge overflow guard used <=, letting a merged min reach the
      RPR_QUANTITY_INF sentinel; tightened to <.

  nocfbot-0037  Fix count slot leak in row pattern recognition absorption
                [behavior change]
      An absorbable leaf VAR exiting inline at max count left its shared
      depth count slot dirty for the sibling group; cleared on exit, with
      the count-clear policy made explicit via Asserts.

  nocfbot-0038  Demote dead runtime checks in the RPR executor to
                assertions

  nocfbot-0039  Fix memory leak in row pattern recognition DEFINE
                evaluation  [behavior change]
      Per-tuple DEFINE evaluation leaked into the wrong context.

  nocfbot-0040  Honor reluctant quantifier for non-leading optional RPR
                variables  [behavior change]
      Reluctant handling existed for leading VARs and groups but not for
      a non-leading optional VAR routed through nfa_route_to_elem; e.g.
      (B A?? C) matched A greedily.  Same skip-first pattern applied.

  nocfbot-0041  Reject column-less compound navigation  [behavior change]
      A compound nav with no column reference is now rejected at parse
      time, instead of being silently accepted with a wrong result.

  nocfbot-0042  Reserve the high varId nibble for RPR control elements
                (the maximum pattern-variable count drops from 251 to 240)

  nocfbot-0043  Generalize quantifier multiplication  [behavior change]
      Replaces the hand-rolled special cases for (child{p,q}){m,n} with a
      general interval-contiguity test, folding cases such as
      (A{2,3}){2,3} -> A{4,9} and (A+){3} -> A{3,} while leaving genuine
      gaps unflattened.

  nocfbot-0044  Tidy up row pattern recognition pattern compilation
  nocfbot-0045  Drop redundant parentheses from row pattern recognition
                ereports
  nocfbot-0046  Tidy up forward declarations and helper placement
  nocfbot-0047  Update the varId documentation
  nocfbot-0048  Reformat the design-decisions chapter in README.rpr
  nocfbot-0049  Point to the absorption-analysis docs from the RPR flag
                definitions

  nocfbot-0050  Fix signed-integer overflow in frame-end clamp
                [behavior change]
      The frame-end clamp computed frameOffset + 1 (int64) before the
      overflow check, so a FOLLOWING offset near PG_INT64_MAX overflowed;
      now added in two checked steps that clamp to PG_INT64_MAX.

  nocfbot-0051  Rework row pattern EXPLAIN deparser to fix grouped
                alternation branches  [EXPLAIN output]
      The bytecode deparser collapsed alternations whose branches were
      quantified groups (e.g. (C | (A B)+ | D)).  Rewritten as recursive
      descent over depth/jump-anchored windows; display-only, execution
      was already correct.

  nocfbot-0052  Handle row pattern navigation nodes in exprTypmod and
                isSimpleNode
  nocfbot-0053  Restore the error cursor for too many row pattern
                variables
  nocfbot-0054  Test deparse of an inline row pattern window
  nocfbot-0055  Fix a mislabeled INITIAL test

  nocfbot-0056  Reject invalid column references in row pattern DEFINE
                clauses  [behavior change]
      Outer-query correlated references and 3-part qualified names in
      DEFINE were reaching an internal "Upper-level Var found where not
      expected" (XX000); both now raise a clean, classified error at
      transformColumnRef.

  nocfbot-0057  Fix shortest match for reluctant nullable quantifiers
                [behavior change]
      An outer reluctant quantifier over a nullable reluctant body, e.g.
      (A??)+?, consumed rows instead of taking the empty match.  The
      count<min branch in nfa_advance_end now mirrors its sibling and
      routes the fast-forward exit first for reluctant elements.

  nocfbot-0058  Compare varno when preserving DEFINE-referenced columns
                [behavior change]
      The allpaths DEFINE-column retention loop compared varattno only;
      it now matches varno/varlevelsup too, dropping over-retention.

  nocfbot-0059  Allow a row pattern quantifier with no space before the
                alternation operator  [behavior change]
      The lexer glues "*|" etc. into one token, so (A*|B) failed.  The
      grammar now recognizes the glued forms via a transient trailing_alt
      flag and splitRPRTrailingAlt() re-splits so "A*|B" == "A* | B".

  nocfbot-0060  Fix outdated function and file references in RPR docs
  nocfbot-0061  Assert that row pattern nesting depth never aliases the
                RPR_DEPTH_NONE sentinel

  nocfbot-0062  Invalidate the row pattern nav slot cache when a window
                partition changes  [behavior change]
      release_partition() now resets nav_slot_pos so a stale cached slot
      position cannot survive a partition boundary.

  nocfbot-0063  Tidy up formatting in row pattern recognition code   (A)
  nocfbot-0064  Modernize idioms in row pattern recognition code     (B)
  nocfbot-0065  Use width-explicit integer limit macros              (C)
                (INT_MAX -> PG_INT32_MAX, the unbounded sentinel)
  nocfbot-0066  Tidy up row pattern recognition regression test comments (D)
  nocfbot-0067  Add row pattern recognition negative and coverage tests (E)
  nocfbot-0068  Use foreach_node and friends in RPR code             (F)
                (foreach + lfirst() -> foreach_node;
                 foreach_current_index, dropping redundant breaks)


Issue-to-patch map (each raised issue -> decision -> landing), by source.
(Earlier incremental cleanup 0001..0016: see [4][5][6].)

Jian He, round 1 (2026-05-26):
  Short-circuit optimization        invited to drive   -> separate series
  Absorption README narrative       accept             -> nocfbot-0017
  DFS expansion                     accept             -> nocfbot-0017
  initialAdvance README mismatch    accept             -> nocfbot-0017
  "absorption" -> "merging" rename  accept (Tatsuo)    -> nocfbot-0031
  Defensive Assert in advance_var   accept             -> nocfbot-0018
  Finalize unnecessary?             keep               -> nocfbot-0018
  Greedy comment label              accept             -> nocfbot-0018
  state->next reset                 decline            -> nocfbot-0018
  visited marking purpose           accept             -> nocfbot-0018
  compareDepth comment              accept             -> nocfbot-0018
  ALT depth invariant Assert        decline            -> nocfbot-0018
  Unused bool return                accept             -> nocfbot-0019
  count >= 3 test coverage          accept             -> nocfbot-0020

Jian He, round 2 (2026-05-28):
  RPRContext consolidation          defer (Tatsuo)     -> D2
  README terminology + typo         accept             -> nocfbot-0021
  get_reduced_frame_status order    keep               -> nocfbot-0022
  states == NULL branch coverage    already reached    -> nocfbot-0023
  currentPos >= -> ==               accept             -> nocfbot-0024
  single-row frame (6.10.2, D1)     reject (Tatsuo)    -> nocfbot-0025
  ExecRPRProcessRow refactor        Datum fix only     -> nocfbot-0026

Jian He, round 3 (2026-05-30) [1] (reply [2]):
  "Tests line N" comments           rephrase           -> nocfbot-0028
  "at the END" wording              accept             -> nocfbot-0028
  uppercase END cleanup             accept             -> nocfbot-0028
  nfa_advance_var count comment     reword             -> nocfbot-0028
  make / clone rename               accept             -> nocfbot-0029
  nfaVisitedNWords field            accept (-> local)  -> nocfbot-0030
  nfaStateSize field                keep               -> (no change)
  drop the elem parameter           keep               -> (no change)

Jian He, off-list (2026-05-15..06-04):
  Per-group banner labels           drop               -> nocfbot-0032
  Dead-context cleanup comment      clarify            -> nocfbot-0033
  rpr.c pg_unreachable refactor     accept             -> nocfbot-0044
  ABSORBABLE doc pointer            accept             -> nocfbot-0049
  has_column_ref necessity          defend             -> (no change)
  CFI dedup                         decline            -> (no change)
  fractional FOLLOWING tests        decline            -> (no change)
  initial/SEEK rename               defer              -> separate series

Tatsuo Ishii + Jian round 4 (2026-05-31..06-02):
  Tatsuo README review              accept             -> nocfbot-0014
  findTargetlistEntrySQL99 static   accept             -> nocfbot-0027
  varId high nibble ("3")           accept             -> nocfbot-0042
  ereport redundant parens          accept             -> nocfbot-0045
  forward-decl / helper placement   accept             -> nocfbot-0046
  varId documentation sync          accept             -> nocfbot-0047
  XII chapter prose reformat        reformat           -> nocfbot-0048
  README 0005 -> 0006 reorder       at submit (Ishii)  -> committer
  double-free question              cannot occur       -> (no change)
  redundant continue                keep               -> (no change)
  non-ASCII section sign            already ASCII      -> (no change)
  empty pattern PATTERN ()          R020 reject right  -> (no change)

in-house static analysis:
  stale comments + window check     fix                -> nocfbot-0034
  unsafe (A{n,})* flattening        fix                -> nocfbot-0035
  INF-valued merge bound            fix                -> nocfbot-0036
  count slot leak                   fix                -> nocfbot-0037
  dead runtime checks -> asserts    fix                -> nocfbot-0038
  DEFINE per-tuple memory leak      fix                -> nocfbot-0039
  reluctant non-leading optional    fix                -> nocfbot-0040
  column-less compound navigation   fix                -> nocfbot-0041
  incomplete quantifier fold (EP-1) generalize         -> nocfbot-0043
  frame-end signed overflow         fix                -> nocfbot-0050
  EXPLAIN deparser grouped-alt      fix                -> nocfbot-0051
  exprTypmod / isSimpleNode nav     fix                -> nocfbot-0052
  errpos for too-many-vars          fix                -> nocfbot-0053
  inline-OVER deparse coverage      fix                -> nocfbot-0054
  INITIAL test mislabel             fix                -> nocfbot-0055
  DEFINE outer / 3-part column ref  fix                -> nocfbot-0056
  reluctant-nullable shortest match fix                -> nocfbot-0057
  allpaths varno comparison         fix                -> nocfbot-0058
  glued quantifier + alternation    fix                -> nocfbot-0059
  nfa_advance / README references   doc                -> nocfbot-0060
  invariant asserts / notes         assert             -> nocfbot-0061
  nav_slot / LAST(x,0) edge cases   defense            -> nocfbot-0062

v48 final fold (off-list sweep + Jian round 5 v47 patch):
  pure formatting                   fold               -> nocfbot-0063
  idioms (palloc_array, Max, ...)   fold               -> nocfbot-0064
  INT_MAX -> PG_INT32_MAX sentinel  fold               -> nocfbot-0065
  regress comment + doc hygiene     fold               -> nocfbot-0066
  new negative / coverage tests     fold               -> nocfbot-0067
  foreach_node + lfirst sweep       fold               -> nocfbot-0068

Please let me know if any of the slicing or the grouping looks off, or
if you would prefer the correctness fixes split out ahead of the
cosmetic fold.

Thanks again to Jian for the careful reading.

Best regards,
Henson

[1] Jian's review, round 3 (2026-05-30):
    https://postgr.es/m/CACJufxEsaU8GQ4yeXTWhAO8VjbrZTh5CpvUqz=4a3T0Cwz44pA@mail.gmail.com

[2] My point-by-point reply to the round-3 review (2026-05-30):
    https://postgr.es/m/CAAAe_zBi1dOtWb2vnwSvGwuU0-bqAOm_7dOM4u-CmukA8xaV5Q@mail.gmail.com

[3] Tatsuo's note on the 0025 ereport wrapping (2026-06-02):
    https://postgr.es/m/20260602.120305.1365406908882385077.ishii@postgresql.org

[4] Earlier incremental post -- nocfbot-0001..0011 (2026-05-09):
    https://postgr.es/m/CAAAe_zCL9UtiYthrSaXCmhFMK6Q3YQ6BQGgae7C9en2k=S9doA@mail.gmail.com

[5] Earlier incremental post -- nocfbot-0012..0015 (2026-05-12):
    https://postgr.es/m/CAAAe_zBg7y5frYxReua1dczXkMK-7fk6bkVo5ZQXDYxpxe0cwA@mail.gmail.com

[6] nocfbot-0016, sent at the time as 0015 (2026-05-26):
    https://postgr.es/m/CAAAe_zD7vCLCb+vxpO3P-NsDUZ=JcN8EGCV0dz0BNgBKsbOGcQ@mail.gmail.com

[7] The 2026-05-30 post -- renumbered 0001..0016 and added 0017..0026:
    https://postgr.es/m/CAAAe_zAuHwqUfqJOD4PDUkWsxTfTytNaandq11Kddw2bfCcpvQ@mail.gmail.com