mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Add further comments to window.c.
FossilOrigin-Name: 900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b
This commit is contained in:
95
src/window.c
95
src/window.c
@@ -1499,19 +1499,78 @@ static void windowAggStep(
|
||||
|
||||
typedef struct WindowCodeArg WindowCodeArg;
|
||||
typedef struct WindowCsrAndReg WindowCsrAndReg;
|
||||
|
||||
/*
|
||||
** See comments above struct WindowCodeArg.
|
||||
*/
|
||||
struct WindowCsrAndReg {
|
||||
int csr;
|
||||
int reg;
|
||||
int csr; /* Cursor number */
|
||||
int reg; /* First in array of peer values */
|
||||
};
|
||||
|
||||
/*
|
||||
** A single instance of this structure is allocated on the stack by
|
||||
** sqlite3WindowCodeStep() and a pointer to it passed to the various helper
|
||||
** routines. This is to reduce the number of arguments required by each
|
||||
** helper function.
|
||||
**
|
||||
** regArg:
|
||||
** Each window function requires an accumulator register (just as an
|
||||
** ordinary aggregate function does). This variable is set to the first
|
||||
** in an array of accumulator registers - one for each window function
|
||||
** in the WindowCodeArg.pMWin list.
|
||||
**
|
||||
** eDelete:
|
||||
** The window functions implementation sometimes caches the input rows
|
||||
** that it processes in a temporary table. If it is not zero, this
|
||||
** variable indicates when rows may be removed from the temp table (in
|
||||
** order to reduce memory requirements - it would always be safe just
|
||||
** to leave them there). Possible values for eDelete are:
|
||||
**
|
||||
** WINDOW_RETURN_ROW:
|
||||
** An input row can be discarded after it is returned to the caller.
|
||||
**
|
||||
** WINDOW_AGGINVERSE:
|
||||
** An input row can be discarded after the window functions xInverse()
|
||||
** callbacks have been invoked in it.
|
||||
**
|
||||
** WINDOW_AGGSTEP:
|
||||
** An input row can be discarded after the window functions xStep()
|
||||
** callbacks have been invoked in it.
|
||||
**
|
||||
** start,current,end
|
||||
** Consider a window-frame similar to the following:
|
||||
**
|
||||
** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING)
|
||||
**
|
||||
** The windows functions implmentation caches the input rows in a temp
|
||||
** table, sorted by "a, b" (it actually populates the cache lazily, and
|
||||
** aggressively removes rows once they are no longer required, but that's
|
||||
** a mere detail). It keeps three cursors open on the temp table. One
|
||||
** (current) that points to the next row to return to the query engine
|
||||
** once its window function values have been calculated. Another (end)
|
||||
** points to the next row to call the xStep() method of each window function
|
||||
** on (so that it is 2 groups ahead of current). And a third (start) that
|
||||
** points to the next row to call the xInverse() method of each window
|
||||
** function on.
|
||||
**
|
||||
** Each cursor (start, current and end) consists of a VDBE cursor
|
||||
** (WindowCsrAndReg.csr) and an array of registers (starting at
|
||||
** WindowCodeArg.reg) that always contains a copy of the peer values
|
||||
** read from the corresponding cursor.
|
||||
**
|
||||
** Depending on the window-frame in question, all three cursors may not
|
||||
** be required. In this case both WindowCodeArg.csr and reg are set to
|
||||
** 0.
|
||||
*/
|
||||
struct WindowCodeArg {
|
||||
Parse *pParse;
|
||||
Window *pMWin;
|
||||
Vdbe *pVdbe;
|
||||
int regGosub;
|
||||
int addrGosub;
|
||||
int regArg;
|
||||
int eDelete;
|
||||
Parse *pParse; /* Parse context */
|
||||
Window *pMWin; /* First in list of functions being processed */
|
||||
Vdbe *pVdbe; /* VDBE object */
|
||||
int addrGosub; /* OP_Gosub to this address to return one row */
|
||||
int regGosub; /* Register used with OP_Gosub(addrGosub) */
|
||||
int regArg; /* First in array of accumulator registers */
|
||||
int eDelete; /* See above */
|
||||
|
||||
WindowCsrAndReg start;
|
||||
WindowCsrAndReg current;
|
||||
@@ -1876,18 +1935,18 @@ static void windowIfNewPeer(
|
||||
*/
|
||||
static void windowCodeRangeTest(
|
||||
WindowCodeArg *p,
|
||||
int op, /* OP_Ge, OP_Gt, or OP_Le */
|
||||
int csr1, /* Cursor number for cursor 1 */
|
||||
int regVal, /* Register containing non-negative number */
|
||||
int csr2, /* Cursor number for cursor 2 */
|
||||
int lbl /* Jump destination if the condition is true */
|
||||
int op, /* OP_Ge, OP_Gt, or OP_Le */
|
||||
int csr1, /* Cursor number for cursor 1 */
|
||||
int regVal, /* Register containing non-negative number */
|
||||
int csr2, /* Cursor number for cursor 2 */
|
||||
int lbl /* Jump destination if condition is true */
|
||||
){
|
||||
Parse *pParse = p->pParse;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for this window */
|
||||
int reg1 = sqlite3GetTempReg(pParse); /* Register for csr1.peerVal+regVal */
|
||||
int reg2 = sqlite3GetTempReg(pParse); /* Regiser for csr2.peerVal */
|
||||
int regString = ++pParse->nMem; /* Register for constant value '' */
|
||||
ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */
|
||||
int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */
|
||||
int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */
|
||||
int regString = ++pParse->nMem; /* Reg. for constant value '' */
|
||||
int arith = OP_Add; /* OP_Add or OP_Subtract */
|
||||
int addrGe; /* Jump destination */
|
||||
|
||||
|
Reference in New Issue
Block a user