Re: Row pattern recognition

From: Tatsuo Ishii <ishii(at)postgresql(dot)org>
To: assam258(at)gmail(dot)com
Cc: zsolt(dot)parragi(at)percona(dot)com, vik(at)postgresfriends(dot)org, er(at)xs4all(dot)nl, jacob(dot)champion(at)enterprisedb(dot)com, david(dot)g(dot)johnston(at)gmail(dot)com, peter(at)eisentraut(dot)org, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Row pattern recognition
Date: 2026-03-16 06:47:32
Message-ID: 20260316.154732.1235248838215291022.ishii@postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> I was not able to find the definition for EEOP_GT. Is this a new one?
>>
>
> You're right -- EEOP_GT does not exist. I oversimplified the example.
>
> In PostgreSQL, comparison operators like `>` are not dedicated opcodes.
> They are dispatched through EEOP_FUNCEXPR variants as regular function
> calls. For example, `price > PREV(price)`:
>
> - The parser resolves `>` to the appropriate pg_operator entry
> - The expression compiler emits an EEOP_FUNCEXPR variant
> - At runtime, op->d.func.fn_addr points to the operator function,

Ok.

> I am afraid ExecEvalExpr does not allow this because ExecEvalExpr does
>> not accept arguments like WindowObject or WindowAggState that are
>> necessary for accessing the tuplestore created for the Window
>> aggregate node.
>
>
> This is the key question. You are right that ExecEvalExpr's signature
> does not accept WindowAggState, and I do not intend to change it.
>
> The approach is to pass WindowAggState through the step's own payload,
> the same way EEOP_WINDOW_FUNC carries WindowFuncExprState in
> op->d.window_func.wfstate. Each ExprEvalStep has a union of per-opcode
> payload structs. A new payload for RPR navigation would look like:
>
> struct
> {
> WindowAggState *winstate; /* access to tuplestore */
> int64 offset; /* signed offset: PREV=-1, NEXT=+1 */
> } rpr_nav;
>
> The expression compiler (ExecInitExprRec) populates this when it
> encounters a PREV/NEXT node, storing the pointer to the enclosing
> WindowAggState. At runtime, EEOP_RPR_NAV_SET retrieves it from the
> payload and uses it to fetch the target row:
>
> /* pseudo-code for EEOP_RPR_NAV_SET */
> winstate = op->d.rpr_nav.winstate;
> /* 1. save current slot into winstate for later restore */
> winstate->saved_outertuple = econtext->ecxt_outertuple;
> /* 2. compute target position */
> target_pos = winstate->currentpos + op->d.rpr_nav.offset;
> /* 3. fetch target row from tuplestore via winstate */
> target_slot = fetch_row_from_tuplestore(winstate, target_pos);
> /* 4. swap */
> econtext->ecxt_outertuple = target_slot;
>
> /* pseudo-code for EEOP_RPR_NAV_RESTORE */
> winstate = op->d.rpr_nav.winstate;
> econtext->ecxt_outertuple = winstate->saved_outertuple;
>
> The key difference from EEOP_WINDOW_FUNC: existing steps read
> precomputed values, but PREV/NEXT requires fetching a *different*
> row at runtime -- because the target depends on the current row
> position during pattern matching, which is not known in advance.
> The mechanism for passing state is the same (step payload), but
> the runtime behavior is a departure from the existing pattern.
>
> I have examined the alternatives carefully:
>
> - The precomputation approach (EEOP_WINDOW_FUNC style) does not apply
> here: there is no fixed set of values to precompute, because the
> target row depends on the current position during pattern matching.
>
> - The three-slot model (current implementation) cannot support variable
> offsets like PREV(price, 3), and requires varno rewriting that adds
> complexity elsewhere.
>
> - A callback-based approach (registering a fetch function in econtext)
> would still require passing WindowAggState somehow, just through a
> different indirection.
>
> The step payload approach is the only path I have found that:
>
> - Leaves ExecEvalExpr's signature unchanged
> - Eliminates varno rewriting entirely
> - Supports variable offsets naturally
> - Extends to FIRST/LAST navigation later

Thank you for the detailed explanation. I agreed the approach.

> If anyone sees a cleaner path, I would genuinely welcome the
> discussion.
>
> I plan to have an experimental implementation ready before next week.
> The initial version will pass WindowAggState broadly; we can
> narrow the interface to the minimum required during review.
> Let's continue the discussion with actual code.

Looking forward to reviewing the implementation.

Best regards,
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2026-03-16 06:50:28 Re: Report bytes and transactions actually sent downtream
Previous Message Peter Smith 2026-03-16 06:35:44 Re: Skipping schema changes in publication