Subject: Query Regarding frame options initialization in Window aggregate state

From: Vallimaharajan G <[email-masked]>
Date: Wed, 27 Mar 2024 14:37:43 +0530

Hi Team,

     I am currently referring to the Postgres source code (psql (PostgreSQL) 14.3) and came across a particular section related to window aggregate initialization that has left me with a question. Specifically, I noticed a conditional case in the initialization of per aggregate (initialize_peraggregate in nodeWindowAgg.c) where the winstate frameOptions is being checked, but it appears that frameOptions is not set before this conditional case. I observed the same behaviour in PG version 16 as well.

/*

* Figure out whether we want to use the moving-aggregate implementation,

* and collect the right set of fields from the pg_attribute entry.

*

* It's possible that an aggregate would supply a safe moving-aggregate

* implementation and an unsafe normal one, in which case our hand is

* forced.  Otherwise, if the frame head can't move, we don't need

* moving-aggregate code.  Even if we'd like to use it, don't do so if the

* aggregate's arguments (and FILTER clause if any) contain any calls to

* volatile functions.  Otherwise, the difference between restarting and

* not restarting the aggregation would be user-visible.

*/

if (!OidIsValid(aggform->aggminvtransfn))

use_ma_code = false; /* sine qua non */

else if (aggform->aggmfinalmodify == AGGMODIFY_READ_ONLY &&

aggform->aggfinalmodify != AGGMODIFY_READ_ONLY)

use_ma_code = true; /* decision forced by safety */

else if (winstate->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)

use_ma_code = false; /* non-moving frame head */

else if (contain_volatile_functions((Node *) wfunc))

use_ma_code = false; /* avoid possible behavioral change */

else

use_ma_code = true; /* yes, let's use it */

if (use_ma_code)

{

peraggstate->transfn_oid = transfn_oid = aggform->aggmtransfn;

peraggstate->invtransfn_oid = invtransfn_oid = aggform->aggminvtransfn;

peraggstate->finalfn_oid = finalfn_oid = aggform->aggmfinalfn;

finalextra = aggform->aggmfinalextra;

finalmodify = aggform->aggmfinalmodify;

aggtranstype = aggform->aggmtranstype;

initvalAttNo = Anum_pg_aggregate_aggminitval;

}

Frame options are being set to winstate after the initialization of peraggregate. (line 2504 in nodeWindowAgg.c)

/* copy frame options to state node for easy access */

winstate->frameOptions = frameOptions;

Could you kindly share the reason why this conditional case was added during the initialization of per aggregate, especially considering that winstate frameOptions is set after this initialization?

Thanks
Vallimaharajan G

---

From: Tom Lane <[email-masked]>
Date: Wed, 27 Mar 2024 12:56:48 -0400

Vallimaharajan G <[email-masked]> writes:
> I am currently referring to the Postgres source code (psql (PostgreSQL) 14.3) and came across a particular section related to window aggregate initialization that has left me with a question. Specifically, I noticed a conditional case in the initialization of per aggregate (initialize_peraggregate in nodeWindowAgg.c) where the winstate frameOptions is being checked, but it appears that frameOptions is not set before this conditional case.

You are right, and that's a bug.  It's not of major consequence ---
it would just cause us to set up for moving-aggregate mode when
we won't ever actually move the frame head -- but it's at least a
little bit inefficient.

While I'm looking at it, there's a pretty obvious typo in the
adjacent comment:

- * and collect the right set of fields from the pg_attribute entry.
+ * and collect the right set of fields from the pg_aggregate entry.

			regards, tom lane