if (!tuplestore_gettupleslot(winstate->buffer, true, true, winstate->framehead_slot))
break; /* 到达分区末尾 */
if (!are_peers(winstate, winstate->temp_slot_2, winstate->framehead_slot))
winstate->frameheadgroup++;
}
ExecClearTuple(winstate->temp_slot_2);
winstate->framehead_valid = true;
}
else
Assert(false);
}
else
Assert(false);
/* 恢复原内存上下文 */
MemoryContextSwitchTo(oldcontext);
}
复制代码
依旧通过一个详细的例子来分析该函数的详细执行过程,案例参考函数eval_windowaggregates。 案例背景:
我们盼望计算每个销售员的累计销售额。使用窗口函数 SUM(sale_amount) OVER (PARTITION BY salesperson_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),即每个销售员的累计销售额是从该销售员的第一个销售日期开始,到当前行的销售额的累积。 SQL 查询:
SELECT salesperson_id, sale_date, sale_amount,
SUM(sale_amount) OVER (PARTITION BY salesperson_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sales
else if (frameOptions & FRAMEOPTION_START_CURRENT_ROW)
{
if (frameOptions & FRAMEOPTION_ROWS)
{
winstate->frameheadpos = winstate->currentpos;
winstate->framehead_valid = true;
}
}
复制代码
如果是 CURRENT ROW,那么帧头就是当前行的位置。在我们的例子中,假设当前行是 2024-01-02,frameheadpos 就是当前行的位置。 第二步:处置惩罚 RANGE 或 GROUPS 模式
如果窗口界说了 RANGE 或 GROUPS,我们必要根据排序规则找到当前行地点的组,并确定该组的第一行作为帧头。 4. 如果没有排序列(ORDER BY):