PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeWindowAgg.h File Reference
#include "nodes/execnodes.h"
Include dependency graph for nodeWindowAgg.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

WindowAggStateExecInitWindowAgg (WindowAgg *node, EState *estate, int eflags)
 
TupleTableSlotExecWindowAgg (WindowAggState *node)
 
void ExecEndWindowAgg (WindowAggState *node)
 
void ExecReScanWindowAgg (WindowAggState *node)
 

Function Documentation

void ExecEndWindowAgg ( WindowAggState node)

Definition at line 2009 of file nodeWindowAgg.c.

References WindowAggState::agg_row_slot, WindowStatePerAggData::aggcontext, WindowAggState::aggcontext, ExecClearTuple(), ExecEndNode(), ExecFreeExprContext(), WindowAggState::first_part_slot, i, MemoryContextDelete(), WindowAggState::numaggs, outerPlan, outerPlanState, WindowAggState::partcontext, WindowAggState::peragg, WindowAggState::perfunc, pfree(), ScanState::ps, PlanState::ps_ExprContext, release_partition(), WindowAggState::ss, ScanState::ss_ScanTupleSlot, WindowAggState::temp_slot_1, WindowAggState::temp_slot_2, and WindowAggState::tmpcontext.

Referenced by ExecEndNode().

2010 {
2012  int i;
2013 
2014  release_partition(node);
2015 
2019  ExecClearTuple(node->temp_slot_1);
2020  ExecClearTuple(node->temp_slot_2);
2021 
2022  /*
2023  * Free both the expr contexts.
2024  */
2025  ExecFreeExprContext(&node->ss.ps);
2026  node->ss.ps.ps_ExprContext = node->tmpcontext;
2027  ExecFreeExprContext(&node->ss.ps);
2028 
2029  for (i = 0; i < node->numaggs; i++)
2030  {
2031  if (node->peragg[i].aggcontext != node->aggcontext)
2033  }
2036 
2037  pfree(node->perfunc);
2038  pfree(node->peragg);
2039 
2040  outerPlan = outerPlanState(node);
2041  ExecEndNode(outerPlan);
2042 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
ScanState ss
Definition: execnodes.h:1784
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:654
ExprContext * ps_ExprContext
Definition: execnodes.h:833
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1050
static void release_partition(WindowAggState *winstate)
TupleTableSlot * temp_slot_1
Definition: execnodes.h:1835
WindowStatePerFunc perfunc
Definition: execnodes.h:1791
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:516
TupleTableSlot * first_part_slot
Definition: execnodes.h:1830
ExprContext * tmpcontext
Definition: execnodes.h:1816
PlanState ps
Definition: execnodes.h:1047
void pfree(void *pointer)
Definition: mcxt.c:950
#define outerPlanState(node)
Definition: execnodes.h:845
TupleTableSlot * temp_slot_2
Definition: execnodes.h:1836
WindowStatePerAgg peragg
Definition: execnodes.h:1792
MemoryContext aggcontext
Definition: execnodes.h:1814
#define outerPlan(node)
Definition: plannodes.h:164
TupleTableSlot * agg_row_slot
Definition: execnodes.h:1834
MemoryContext aggcontext
int i
MemoryContext partcontext
Definition: execnodes.h:1813
WindowAggState* ExecInitWindowAgg ( WindowAgg node,
EState estate,
int  eflags 
)

Definition at line 1768 of file nodeWindowAgg.c.

References ACL_EXECUTE, ACL_KIND_PROC, aclcheck_error(), ACLCHECK_OK, WindowAggState::agg_row_slot, WindowAggState::agg_winobj, WindowAggState::aggcontext, WindowStatePerFuncData::aggno, WindowAggState::all_first, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), WindowFuncExprState::args, WindowObjectData::argstates, Assert, contain_volatile_functions(), CurrentMemoryContext, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_per_query_memory, elog, WindowAgg::endOffset, WindowAggState::endOffset, equal(), ERROR, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignProjectionInfo(), ExecAssignResultTypeFromTL(), ExecAssignScanTypeFromOuterPlan(), ExecInitExpr(), ExecInitExtraTupleSlot(), ExecInitNode(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ExecSetSlotDescriptor(), execTuplesMatchPrepare(), WindowAggState::first_part_slot, WindowStatePerFuncData::flinfo, fmgr_info_cxt(), fmgr_info_set_expr, WindowAgg::frameOptions, WindowAggState::frameOptions, WindowAggState::funcs, get_func_name(), get_typlenbyval(), GetUserId(), i, initialize_peragg(), WindowFunc::inputcollid, InvokeFunctionExecuteHook, lfirst, list_length(), WindowObjectData::localmem, makeNode, WindowObjectData::markptr, WindowAggState::more_partitions, NIL, NULL, WindowAggState::numaggs, WindowStatePerFuncData::numArguments, WindowAggState::numfuncs, WindowAggState::ordEqfunctions, WindowAgg::ordNumCols, WindowAgg::ordOperators, outerPlan, outerPlanState, palloc0(), WindowAggState::partcontext, WindowAggState::partEqfunctions, WindowAggState::partition_spooled, WindowAgg::partNumCols, WindowAgg::partOperators, WindowAggState::peragg, WindowAggState::perfunc, pg_proc_aclcheck(), WindowStatePerFuncData::plain_agg, WindowAgg::plan, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, Plan::qual, PlanState::qual, WindowObjectData::readptr, WindowStatePerFuncData::resulttypeByVal, WindowStatePerFuncData::resulttypeLen, WindowAggState::ss, ScanState::ss_ScanTupleSlot, WindowAgg::startOffset, WindowAggState::startOffset, PlanState::state, WindowAggState::temp_slot_1, WindowAggState::temp_slot_2, WindowAggState::tmpcontext, TupleTableSlot::tts_tupleDescriptor, WindowStatePerFuncData::wfunc, WindowFuncExprState::wfunc, WindowStatePerAggData::wfuncno, WindowFuncExprState::wfuncno, WindowStatePerFuncData::wfuncstate, WindowFunc::winagg, WindowStatePerFuncData::winCollation, WindowFunc::winfnoid, WindowStatePerFuncData::winobj, WindowFunc::winref, WindowAgg::winref, WindowObjectData::winstate, and WindowFunc::wintype.

Referenced by ExecInitNode().

1769 {
1770  WindowAggState *winstate;
1771  Plan *outerPlan;
1772  ExprContext *econtext;
1773  ExprContext *tmpcontext;
1774  WindowStatePerFunc perfunc;
1775  WindowStatePerAgg peragg;
1776  int numfuncs,
1777  wfuncno,
1778  numaggs,
1779  aggno;
1780  ListCell *l;
1781 
1782  /* check for unsupported flags */
1783  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
1784 
1785  /*
1786  * create state structure
1787  */
1788  winstate = makeNode(WindowAggState);
1789  winstate->ss.ps.plan = (Plan *) node;
1790  winstate->ss.ps.state = estate;
1791 
1792  /*
1793  * Create expression contexts. We need two, one for per-input-tuple
1794  * processing and one for per-output-tuple processing. We cheat a little
1795  * by using ExecAssignExprContext() to build both.
1796  */
1797  ExecAssignExprContext(estate, &winstate->ss.ps);
1798  tmpcontext = winstate->ss.ps.ps_ExprContext;
1799  winstate->tmpcontext = tmpcontext;
1800  ExecAssignExprContext(estate, &winstate->ss.ps);
1801 
1802  /* Create long-lived context for storage of partition-local memory etc */
1803  winstate->partcontext =
1805  "WindowAgg Partition",
1807 
1808  /*
1809  * Create mid-lived context for aggregate trans values etc.
1810  *
1811  * Note that moving aggregates each use their own private context, not
1812  * this one.
1813  */
1814  winstate->aggcontext =
1816  "WindowAgg Aggregates",
1818 
1819  /*
1820  * tuple table initialization
1821  */
1822  ExecInitScanTupleSlot(estate, &winstate->ss);
1823  ExecInitResultTupleSlot(estate, &winstate->ss.ps);
1824  winstate->first_part_slot = ExecInitExtraTupleSlot(estate);
1825  winstate->agg_row_slot = ExecInitExtraTupleSlot(estate);
1826  winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate);
1827  winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate);
1828 
1829  /*
1830  * WindowAgg nodes never have quals, since they can only occur at the
1831  * logical top level of a query (ie, after any WHERE or HAVING filters)
1832  */
1833  Assert(node->plan.qual == NIL);
1834  winstate->ss.ps.qual = NULL;
1835 
1836  /*
1837  * initialize child nodes
1838  */
1839  outerPlan = outerPlan(node);
1840  outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags);
1841 
1842  /*
1843  * initialize source tuple type (which is also the tuple type that we'll
1844  * store in the tuplestore and use in all our working slots).
1845  */
1846  ExecAssignScanTypeFromOuterPlan(&winstate->ss);
1847 
1856 
1857  /*
1858  * Initialize result tuple type and projection info.
1859  */
1860  ExecAssignResultTypeFromTL(&winstate->ss.ps);
1861  ExecAssignProjectionInfo(&winstate->ss.ps, NULL);
1862 
1863  /* Set up data for comparing tuples */
1864  if (node->partNumCols > 0)
1866  node->partOperators);
1867  if (node->ordNumCols > 0)
1869  node->ordOperators);
1870 
1871  /*
1872  * WindowAgg nodes use aggvalues and aggnulls as well as Agg nodes.
1873  */
1874  numfuncs = winstate->numfuncs;
1875  numaggs = winstate->numaggs;
1876  econtext = winstate->ss.ps.ps_ExprContext;
1877  econtext->ecxt_aggvalues = (Datum *) palloc0(sizeof(Datum) * numfuncs);
1878  econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numfuncs);
1879 
1880  /*
1881  * allocate per-wfunc/per-agg state information.
1882  */
1883  perfunc = (WindowStatePerFunc) palloc0(sizeof(WindowStatePerFuncData) * numfuncs);
1884  peragg = (WindowStatePerAgg) palloc0(sizeof(WindowStatePerAggData) * numaggs);
1885  winstate->perfunc = perfunc;
1886  winstate->peragg = peragg;
1887 
1888  wfuncno = -1;
1889  aggno = -1;
1890  foreach(l, winstate->funcs)
1891  {
1892  WindowFuncExprState *wfuncstate = (WindowFuncExprState *) lfirst(l);
1893  WindowFunc *wfunc = wfuncstate->wfunc;
1894  WindowStatePerFunc perfuncstate;
1895  AclResult aclresult;
1896  int i;
1897 
1898  if (wfunc->winref != node->winref) /* planner screwed up? */
1899  elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u",
1900  wfunc->winref, node->winref);
1901 
1902  /* Look for a previous duplicate window function */
1903  for (i = 0; i <= wfuncno; i++)
1904  {
1905  if (equal(wfunc, perfunc[i].wfunc) &&
1906  !contain_volatile_functions((Node *) wfunc))
1907  break;
1908  }
1909  if (i <= wfuncno)
1910  {
1911  /* Found a match to an existing entry, so just mark it */
1912  wfuncstate->wfuncno = i;
1913  continue;
1914  }
1915 
1916  /* Nope, so assign a new PerAgg record */
1917  perfuncstate = &perfunc[++wfuncno];
1918 
1919  /* Mark WindowFunc state node with assigned index in the result array */
1920  wfuncstate->wfuncno = wfuncno;
1921 
1922  /* Check permission to call window function */
1923  aclresult = pg_proc_aclcheck(wfunc->winfnoid, GetUserId(),
1924  ACL_EXECUTE);
1925  if (aclresult != ACLCHECK_OK)
1926  aclcheck_error(aclresult, ACL_KIND_PROC,
1927  get_func_name(wfunc->winfnoid));
1928  InvokeFunctionExecuteHook(wfunc->winfnoid);
1929 
1930  /* Fill in the perfuncstate data */
1931  perfuncstate->wfuncstate = wfuncstate;
1932  perfuncstate->wfunc = wfunc;
1933  perfuncstate->numArguments = list_length(wfuncstate->args);
1934 
1935  fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo,
1936  econtext->ecxt_per_query_memory);
1937  fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo);
1938 
1939  perfuncstate->winCollation = wfunc->inputcollid;
1940 
1941  get_typlenbyval(wfunc->wintype,
1942  &perfuncstate->resulttypeLen,
1943  &perfuncstate->resulttypeByVal);
1944 
1945  /*
1946  * If it's really just a plain aggregate function, we'll emulate the
1947  * Agg environment for it.
1948  */
1949  perfuncstate->plain_agg = wfunc->winagg;
1950  if (wfunc->winagg)
1951  {
1952  WindowStatePerAgg peraggstate;
1953 
1954  perfuncstate->aggno = ++aggno;
1955  peraggstate = &winstate->peragg[aggno];
1956  initialize_peragg(winstate, wfunc, peraggstate);
1957  peraggstate->wfuncno = wfuncno;
1958  }
1959  else
1960  {
1962 
1963  winobj->winstate = winstate;
1964  winobj->argstates = wfuncstate->args;
1965  winobj->localmem = NULL;
1966  perfuncstate->winobj = winobj;
1967  }
1968  }
1969 
1970  /* Update numfuncs, numaggs to match number of unique functions found */
1971  winstate->numfuncs = wfuncno + 1;
1972  winstate->numaggs = aggno + 1;
1973 
1974  /* Set up WindowObject for aggregates, if needed */
1975  if (winstate->numaggs > 0)
1976  {
1977  WindowObject agg_winobj = makeNode(WindowObjectData);
1978 
1979  agg_winobj->winstate = winstate;
1980  agg_winobj->argstates = NIL;
1981  agg_winobj->localmem = NULL;
1982  /* make sure markptr = -1 to invalidate. It may not get used */
1983  agg_winobj->markptr = -1;
1984  agg_winobj->readptr = -1;
1985  winstate->agg_winobj = agg_winobj;
1986  }
1987 
1988  /* copy frame options to state node for easy access */
1989  winstate->frameOptions = node->frameOptions;
1990 
1991  /* initialize frame bound offset expressions */
1992  winstate->startOffset = ExecInitExpr((Expr *) node->startOffset,
1993  (PlanState *) winstate);
1994  winstate->endOffset = ExecInitExpr((Expr *) node->endOffset,
1995  (PlanState *) winstate);
1996 
1997  winstate->all_first = true;
1998  winstate->partition_spooled = false;
1999  winstate->more_partitions = false;
2000 
2001  return winstate;
2002 }
int ordNumCols
Definition: plannodes.h:797
#define NIL
Definition: pg_list.h:69
List * qual
Definition: plannodes.h:135
ExprState * endOffset
Definition: execnodes.h:1809
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
Datum * ecxt_aggvalues
Definition: execnodes.h:213
struct WindowStatePerAggData * WindowStatePerAgg
Definition: execnodes.h:1780
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:2962
Oid GetUserId(void)
Definition: miscinit.c:283
ScanState ss
Definition: execnodes.h:1784
ExprContext * ps_ExprContext
Definition: execnodes.h:833
Definition: nodes.h:509
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1050
struct WindowStatePerFuncData * WindowStatePerFunc
Definition: execnodes.h:1779
FmgrInfo * partEqfunctions
Definition: execnodes.h:1793
WindowFuncExprState * wfuncstate
Definition: nodeWindowAgg.c:78
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:951
EState * state
Definition: execnodes.h:805
Index winref
Definition: primnodes.h:361
TupleTableSlot * temp_slot_1
Definition: execnodes.h:1835
WindowStatePerFunc perfunc
Definition: execnodes.h:1791
Oid * ordOperators
Definition: plannodes.h:799
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:440
TupleTableSlot * first_part_slot
Definition: execnodes.h:1830
ExprContext * tmpcontext
Definition: execnodes.h:1816
PlanState ps
Definition: execnodes.h:1047
struct WindowObjectData * agg_winobj
Definition: execnodes.h:1802
Node * startOffset
Definition: plannodes.h:801
static WindowStatePerAggData * initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, WindowStatePerAgg peraggstate)
#define ERROR
Definition: elog.h:43
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1412
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:845
TupleTableSlot * temp_slot_2
Definition: execnodes.h:1836
WindowStatePerAgg peragg
Definition: execnodes.h:1792
ExprState * startOffset
Definition: execnodes.h:1808
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:487
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
Node * endOffset
Definition: plannodes.h:802
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:104
int partNumCols
Definition: plannodes.h:794
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
MemoryContext aggcontext
Definition: execnodes.h:1814
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:179
#define outerPlan(node)
Definition: plannodes.h:164
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
bool * ecxt_aggnulls
Definition: execnodes.h:214
WindowAggState * winstate
Definition: nodeWindowAgg.c:62
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
void * palloc0(Size size)
Definition: mcxt.c:878
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:372
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
TupleTableSlot * agg_row_slot
Definition: execnodes.h:1834
Plan * plan
Definition: execnodes.h:803
bool more_partitions
Definition: execnodes.h:1823
FmgrInfo * ordEqfunctions
Definition: execnodes.h:1794
Oid * partOperators
Definition: plannodes.h:796
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
Index winref
Definition: plannodes.h:793
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:418
static int list_length(const List *l)
Definition: pg_list.h:89
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2001
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
ExprState * qual
Definition: execnodes.h:817
bool partition_spooled
Definition: execnodes.h:1820
void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
Definition: execUtils.c:552
#define ACL_EXECUTE
Definition: parsenodes.h:79
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4446
int i
Plan plan
Definition: plannodes.h:792
MemoryContext partcontext
Definition: execnodes.h:1813
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:113
#define elog
Definition: elog.h:219
int frameOptions
Definition: plannodes.h:800
WindowFunc * wfunc
Definition: execnodes.h:635
FmgrInfo * execTuplesMatchPrepare(int numCols, Oid *eqOperators)
Definition: execGrouping.c:204
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:140
void ExecReScanWindowAgg ( WindowAggState node)

Definition at line 2049 of file nodeWindowAgg.c.

References WindowAggState::agg_row_slot, WindowAggState::all_done, WindowAggState::all_first, PlanState::chgParam, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExecClearTuple(), ExecReScan(), WindowAggState::first_part_slot, MemSet, NULL, WindowAggState::numfuncs, outerPlan, outerPlanState, ScanState::ps, PlanState::ps_ExprContext, release_partition(), WindowAggState::ss, ScanState::ss_ScanTupleSlot, WindowAggState::temp_slot_1, and WindowAggState::temp_slot_2.

Referenced by ExecReScan().

2050 {
2052  ExprContext *econtext = node->ss.ps.ps_ExprContext;
2053 
2054  node->all_done = false;
2055  node->all_first = true;
2056 
2057  /* release tuplestore et al */
2058  release_partition(node);
2059 
2060  /* release all temp tuples, but especially first_part_slot */
2064  ExecClearTuple(node->temp_slot_1);
2065  ExecClearTuple(node->temp_slot_2);
2066 
2067  /* Forget current wfunc values */
2068  MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numfuncs);
2069  MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numfuncs);
2070 
2071  /*
2072  * if chgParam of subnode is not null then plan will be re-scanned by
2073  * first ExecProcNode.
2074  */
2075  if (outerPlan->chgParam == NULL)
2076  ExecReScan(outerPlan);
2077 }
Datum * ecxt_aggvalues
Definition: execnodes.h:213
ScanState ss
Definition: execnodes.h:1784
ExprContext * ps_ExprContext
Definition: execnodes.h:833
void ExecReScan(PlanState *node)
Definition: execAmi.c:75
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
#define MemSet(start, val, len)
Definition: c.h:857
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1050
static void release_partition(WindowAggState *winstate)
TupleTableSlot * temp_slot_1
Definition: execnodes.h:1835
TupleTableSlot * first_part_slot
Definition: execnodes.h:1830
PlanState ps
Definition: execnodes.h:1047
#define outerPlanState(node)
Definition: execnodes.h:845
TupleTableSlot * temp_slot_2
Definition: execnodes.h:1836
Bitmapset * chgParam
Definition: execnodes.h:827
#define outerPlan(node)
Definition: plannodes.h:164
bool * ecxt_aggnulls
Definition: execnodes.h:214
uintptr_t Datum
Definition: postgres.h:372
TupleTableSlot * agg_row_slot
Definition: execnodes.h:1834
#define NULL
Definition: c.h:229
TupleTableSlot* ExecWindowAgg ( WindowAggState node)

Definition at line 1591 of file nodeWindowAgg.c.

References WindowAggState::all_done, WindowAggState::all_first, Assert, begin_partition(), WindowAggState::buffer, WindowAggState::current_ptr, WindowAggState::currentpos, datumCopy(), DatumGetInt64, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_outertuple, elog, WindowAggState::endOffset, WindowAggState::endOffsetValue, ereport, errcode(), errmsg(), ERROR, eval_windowaggregates(), eval_windowfunction(), ExecEvalExprSwitchContext(), ExecProject(), ExprState::expr, exprType(), WindowAggState::framehead_valid, FRAMEOPTION_END_VALUE, FRAMEOPTION_ROWS, FRAMEOPTION_START_VALUE, WindowAggState::frameOptions, WindowAggState::frametail_valid, get_typlenbyval(), i, WindowAggState::more_partitions, NULL, WindowAggState::numaggs, WindowAggState::numfuncs, WindowAggState::partition_spooled, WindowAggState::perfunc, WindowStatePerFuncData::plain_agg, ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_ProjInfo, release_partition(), ResetExprContext, spool_tuples(), WindowAggState::spooled_rows, WindowAggState::ss, ScanState::ss_ScanTupleSlot, WindowAggState::startOffset, WindowAggState::startOffsetValue, tuplestore_gettupleslot(), tuplestore_select_read_pointer(), tuplestore_trim(), value, WindowFuncExprState::wfuncno, and WindowStatePerFuncData::wfuncstate.

Referenced by ExecProcNode().

1592 {
1593  ExprContext *econtext;
1594  int i;
1595  int numfuncs;
1596 
1597  if (winstate->all_done)
1598  return NULL;
1599 
1600  /*
1601  * Compute frame offset values, if any, during first call.
1602  */
1603  if (winstate->all_first)
1604  {
1605  int frameOptions = winstate->frameOptions;
1606  ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
1607  Datum value;
1608  bool isnull;
1609  int16 len;
1610  bool byval;
1611 
1612  if (frameOptions & FRAMEOPTION_START_VALUE)
1613  {
1614  Assert(winstate->startOffset != NULL);
1615  value = ExecEvalExprSwitchContext(winstate->startOffset,
1616  econtext,
1617  &isnull);
1618  if (isnull)
1619  ereport(ERROR,
1620  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1621  errmsg("frame starting offset must not be null")));
1622  /* copy value into query-lifespan context */
1623  get_typlenbyval(exprType((Node *) winstate->startOffset->expr),
1624  &len, &byval);
1625  winstate->startOffsetValue = datumCopy(value, byval, len);
1626  if (frameOptions & FRAMEOPTION_ROWS)
1627  {
1628  /* value is known to be int8 */
1629  int64 offset = DatumGetInt64(value);
1630 
1631  if (offset < 0)
1632  ereport(ERROR,
1633  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1634  errmsg("frame starting offset must not be negative")));
1635  }
1636  }
1637  if (frameOptions & FRAMEOPTION_END_VALUE)
1638  {
1639  Assert(winstate->endOffset != NULL);
1640  value = ExecEvalExprSwitchContext(winstate->endOffset,
1641  econtext,
1642  &isnull);
1643  if (isnull)
1644  ereport(ERROR,
1645  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1646  errmsg("frame ending offset must not be null")));
1647  /* copy value into query-lifespan context */
1648  get_typlenbyval(exprType((Node *) winstate->endOffset->expr),
1649  &len, &byval);
1650  winstate->endOffsetValue = datumCopy(value, byval, len);
1651  if (frameOptions & FRAMEOPTION_ROWS)
1652  {
1653  /* value is known to be int8 */
1654  int64 offset = DatumGetInt64(value);
1655 
1656  if (offset < 0)
1657  ereport(ERROR,
1658  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1659  errmsg("frame ending offset must not be negative")));
1660  }
1661  }
1662  winstate->all_first = false;
1663  }
1664 
1665  if (winstate->buffer == NULL)
1666  {
1667  /* Initialize for first partition and set current row = 0 */
1668  begin_partition(winstate);
1669  /* If there are no input rows, we'll detect that and exit below */
1670  }
1671  else
1672  {
1673  /* Advance current row within partition */
1674  winstate->currentpos++;
1675  /* This might mean that the frame moves, too */
1676  winstate->framehead_valid = false;
1677  winstate->frametail_valid = false;
1678  }
1679 
1680  /*
1681  * Spool all tuples up to and including the current row, if we haven't
1682  * already
1683  */
1684  spool_tuples(winstate, winstate->currentpos);
1685 
1686  /* Move to the next partition if we reached the end of this partition */
1687  if (winstate->partition_spooled &&
1688  winstate->currentpos >= winstate->spooled_rows)
1689  {
1690  release_partition(winstate);
1691 
1692  if (winstate->more_partitions)
1693  {
1694  begin_partition(winstate);
1695  Assert(winstate->spooled_rows > 0);
1696  }
1697  else
1698  {
1699  winstate->all_done = true;
1700  return NULL;
1701  }
1702  }
1703 
1704  /* final output execution is in ps_ExprContext */
1705  econtext = winstate->ss.ps.ps_ExprContext;
1706 
1707  /* Clear the per-output-tuple context for current row */
1708  ResetExprContext(econtext);
1709 
1710  /*
1711  * Read the current row from the tuplestore, and save in ScanTupleSlot.
1712  * (We can't rely on the outerplan's output slot because we may have to
1713  * read beyond the current row. Also, we have to actually copy the row
1714  * out of the tuplestore, since window function evaluation might cause the
1715  * tuplestore to dump its state to disk.)
1716  *
1717  * Current row must be in the tuplestore, since we spooled it above.
1718  */
1719  tuplestore_select_read_pointer(winstate->buffer, winstate->current_ptr);
1720  if (!tuplestore_gettupleslot(winstate->buffer, true, true,
1721  winstate->ss.ss_ScanTupleSlot))
1722  elog(ERROR, "unexpected end of tuplestore");
1723 
1724  /*
1725  * Evaluate true window functions
1726  */
1727  numfuncs = winstate->numfuncs;
1728  for (i = 0; i < numfuncs; i++)
1729  {
1730  WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]);
1731 
1732  if (perfuncstate->plain_agg)
1733  continue;
1734  eval_windowfunction(winstate, perfuncstate,
1735  &(econtext->ecxt_aggvalues[perfuncstate->wfuncstate->wfuncno]),
1736  &(econtext->ecxt_aggnulls[perfuncstate->wfuncstate->wfuncno]));
1737  }
1738 
1739  /*
1740  * Evaluate aggregates
1741  */
1742  if (winstate->numaggs > 0)
1743  eval_windowaggregates(winstate);
1744 
1745  /*
1746  * Truncate any no-longer-needed rows from the tuplestore.
1747  */
1748  tuplestore_trim(winstate->buffer);
1749 
1750  /*
1751  * Form and return a projection tuple using the windowfunc results and the
1752  * current row. Setting ecxt_outertuple arranges that any Vars will be
1753  * evaluated with respect to that row.
1754  */
1755  econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
1756 
1757  return ExecProject(winstate->ss.ps.ps_ProjInfo);
1758 }
signed short int16
Definition: c.h:255
Datum * ecxt_aggvalues
Definition: execnodes.h:213
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:280
void tuplestore_trim(Tuplestorestate *state)
Definition: tuplestore.c:1360
#define FRAMEOPTION_START_VALUE
Definition: parsenodes.h:520
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
static void release_partition(WindowAggState *winstate)
WindowFuncExprState * wfuncstate
Definition: nodeWindowAgg.c:78
static void spool_tuples(WindowAggState *winstate, int64 pos)
#define ERROR
Definition: elog.h:43
#define DatumGetInt64(X)
Definition: postgres.h:613
#define ereport(elevel, rest)
Definition: elog.h:122
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:128
static void eval_windowaggregates(WindowAggState *winstate)
bool * ecxt_aggnulls
Definition: execnodes.h:214
uintptr_t Datum
Definition: postgres.h:372
static void begin_partition(WindowAggState *winstate)
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
Definition: tuplestore.c:1078
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:199
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2001
#define FRAMEOPTION_ROWS
Definition: parsenodes.h:507
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:473
#define elog
Definition: elog.h:219
static struct @121 value
#define FRAMEOPTION_END_VALUE
Definition: parsenodes.h:522
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
Definition: executor.h:308
static void eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, Datum *result, bool *isnull)
#define ResetExprContext(econtext)
Definition: executor.h:449