aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/execnodes.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-02-07 00:06:50 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-02-07 00:06:56 -0500
commit0a459cec96d3856f476c2db298c6b52f592894e8 (patch)
tree3d10f137b48de039c46914fa8e854bd69daaaec1 /src/include/nodes/execnodes.h
parent23209457314f6fd89fcd251a8173b0129aaa95a2 (diff)
downloadpostgresql-0a459cec96d3856f476c2db298c6b52f592894e8.tar.gz
postgresql-0a459cec96d3856f476c2db298c6b52f592894e8.zip
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING" frame boundaries in window functions. We'd punted on that back in the original patch to add window functions, because it was not clear how to do it in a reasonably data-type-extensible fashion. That problem is resolved here by adding the ability for btree operator classes to provide an "in_range" support function that defines how to add or subtract the RANGE offset value. Factoring it this way also allows the operator class to avoid overflow problems near the ends of the datatype's range, if it wishes to expend effort on that. (In the committed patch, the integer opclasses handle that issue, but it did not seem worth the trouble to avoid overflow failures for datetime types.) The patch includes in_range support for the integer_ops opfamily (int2/int4/int8) as well as the standard datetime types. Support for other numeric types has been requested, but that seems like suitable material for a follow-on patch. In addition, the patch adds GROUPS mode which counts the offset in ORDER-BY peer groups rather than rows, and it adds the frame_exclusion options specified by SQL:2011. As far as I can see, we are now fully up to spec on window framing options. Existing behaviors remain unchanged, except that I changed the errcode for a couple of existing error reports to meet the SQL spec's expectation that negative "offset" values should be reported as SQLSTATE 22013. Internally and in relevant parts of the documentation, we now consistently use the terminology "offset PRECEDING/FOLLOWING" rather than "value PRECEDING/FOLLOWING", since the term "value" is confusingly vague. Oliver Ford, reviewed and whacked around some by me Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
Diffstat (limited to 'src/include/nodes/execnodes.h')
-rw-r--r--src/include/nodes/execnodes.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a2a2a9f3d4d..54ce63f1477 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1885,11 +1885,14 @@ typedef struct WindowAggState
FmgrInfo *partEqfunctions; /* equality funcs for partition columns */
FmgrInfo *ordEqfunctions; /* equality funcs for ordering columns */
Tuplestorestate *buffer; /* stores rows of current partition */
- int current_ptr; /* read pointer # for current */
+ int current_ptr; /* read pointer # for current row */
+ int framehead_ptr; /* read pointer # for frame head, if used */
+ int frametail_ptr; /* read pointer # for frame tail, if used */
+ int grouptail_ptr; /* read pointer # for group tail, if used */
int64 spooled_rows; /* total # of rows in buffer */
int64 currentpos; /* position of current row in partition */
int64 frameheadpos; /* current frame head position */
- int64 frametailpos; /* current frame tail position */
+ int64 frametailpos; /* current frame tail position (frame end+1) */
/* use struct pointer to avoid including windowapi.h here */
struct WindowObjectData *agg_winobj; /* winobj for aggregate fetches */
int64 aggregatedbase; /* start row for current aggregates */
@@ -1901,6 +1904,20 @@ typedef struct WindowAggState
Datum startOffsetValue; /* result of startOffset evaluation */
Datum endOffsetValue; /* result of endOffset evaluation */
+ /* these fields are used with RANGE offset PRECEDING/FOLLOWING: */
+ FmgrInfo startInRangeFunc; /* in_range function for startOffset */
+ FmgrInfo endInRangeFunc; /* in_range function for endOffset */
+ Oid inRangeColl; /* collation for in_range tests */
+ bool inRangeAsc; /* use ASC sort order for in_range tests? */
+ bool inRangeNullsFirst; /* nulls sort first for in_range tests? */
+
+ /* these fields are used in GROUPS mode: */
+ int64 currentgroup; /* peer group # of current row in partition */
+ int64 frameheadgroup; /* peer group # of frame head row */
+ int64 frametailgroup; /* peer group # of frame tail row */
+ int64 groupheadpos; /* current row's peer group head position */
+ int64 grouptailpos; /* " " " " tail position (group end+1) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -1916,9 +1933,13 @@ typedef struct WindowAggState
* date for current row */
bool frametail_valid; /* true if frametailpos is known up to
* date for current row */
+ bool grouptail_valid; /* true if grouptailpos is known up to
+ * date for current row */
TupleTableSlot *first_part_slot; /* first tuple of current or next
* partition */
+ TupleTableSlot *framehead_slot; /* first tuple of current frame */
+ TupleTableSlot *frametail_slot; /* first tuple after current frame */
/* temporary slots for tuples fetched back from tuplestore */
TupleTableSlot *agg_row_slot;