Thread

Commits

  1. Fix unnecessary use of moving-aggregate mode with non-moving frame.

  1. Query Regarding frame options initialization in Window aggregate state

    Vallimaharajan <vallimaharajan.gs@zohocorp.com> — 2024-03-27T09:07:43Z

    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
  2. Re: Query Regarding frame options initialization in Window aggregate state

    Tom Lane <tgl@sss.pgh.pa.us> — 2024-03-27T16:56:48Z

    Vallimaharajan G <vallimaharajan.gs@zohocorp.com> 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