aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-12-28 18:54:01 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-12-28 18:54:01 +0000
commit95b07bc7f5010233f52f9d11da74e2e5b653b0a7 (patch)
tree48f5858bf4eca1bfb316ef02bb959ca85f568e0a /src/include
parent38e9348282e9d078487147ba8a85aebec54e3a08 (diff)
downloadpostgresql-95b07bc7f5010233f52f9d11da74e2e5b653b0a7.tar.gz
postgresql-95b07bc7f5010233f52f9d11da74e2e5b653b0a7.zip
Support window functions a la SQL:2008.
Hitoshi Harada, with some kibitzing from Heikki and Tom.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/pg_proc.h34
-rw-r--r--src/include/executor/nodeWindowAgg.h25
-rw-r--r--src/include/fmgr.h4
-rw-r--r--src/include/nodes/execnodes.h69
-rw-r--r--src/include/nodes/nodes.h9
-rw-r--r--src/include/nodes/parsenodes.h51
-rw-r--r--src/include/nodes/plannodes.h17
-rw-r--r--src/include/nodes/primnodes.h17
-rw-r--r--src/include/nodes/relation.h3
-rw-r--r--src/include/optimizer/clauses.h13
-rw-r--r--src/include/optimizer/cost.h6
-rw-r--r--src/include/optimizer/planmain.h7
-rw-r--r--src/include/optimizer/tlist.h4
-rw-r--r--src/include/parser/parse_agg.h7
-rw-r--r--src/include/parser/parse_clause.h10
-rw-r--r--src/include/parser/parse_func.h5
-rw-r--r--src/include/parser/parse_node.h10
-rw-r--r--src/include/rewrite/rewriteManip.h4
-rw-r--r--src/include/utils/array.h4
-rw-r--r--src/include/utils/builtins.h19
-rw-r--r--src/include/utils/errcodes.h5
-rw-r--r--src/include/utils/tuplestore.h4
-rw-r--r--src/include/windowapi.h64
24 files changed, 362 insertions, 33 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 2f5ae35ef9f..21bbd429ae8 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.513 2008/12/19 18:25:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.514 2008/12/28 18:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200812192
+#define CATALOG_VERSION_NO 200812281
#endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index be632befc92..3082c58a582 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.533 2008/12/19 18:25:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.534 2008/12/28 18:53:59 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -4635,6 +4635,38 @@ DESCR("record greater than or equal");
DATA(insert OID = 2987 ( btrecordcmp PGNSP PGUID 12 1 0 0 f f f t f i 2 0 23 "2249 2249" _null_ _null_ _null_ _null_ btrecordcmp _null_ _null_ _null_ ));
DESCR("btree less-equal-greater");
+/* SQL-spec window functions */
+DATA(insert OID = 3100 ( row_number PGNSP PGUID 12 1 0 0 f t f f f i 0 0 20 "" _null_ _null_ _null_ _null_ window_row_number _null_ _null_ _null_ ));
+DESCR("row number within partition");
+DATA(insert OID = 3101 ( rank PGNSP PGUID 12 1 0 0 f t f f f i 0 0 20 "" _null_ _null_ _null_ _null_ window_rank _null_ _null_ _null_ ));
+DESCR("integer rank with gaps");
+DATA(insert OID = 3102 ( dense_rank PGNSP PGUID 12 1 0 0 f t f f f i 0 0 20 "" _null_ _null_ _null_ _null_ window_dense_rank _null_ _null_ _null_ ));
+DESCR("integer rank without gaps");
+DATA(insert OID = 3103 ( percent_rank PGNSP PGUID 12 1 0 0 f t f f f i 0 0 701 "" _null_ _null_ _null_ _null_ window_percent_rank _null_ _null_ _null_ ));
+DESCR("fractional rank within partition");
+DATA(insert OID = 3104 ( cume_dist PGNSP PGUID 12 1 0 0 f t f f f i 0 0 701 "" _null_ _null_ _null_ _null_ window_cume_dist _null_ _null_ _null_ ));
+DESCR("fractional row number within partition");
+DATA(insert OID = 3105 ( ntile PGNSP PGUID 12 1 0 0 f t f t f i 1 0 23 "23" _null_ _null_ _null_ _null_ window_ntile _null_ _null_ _null_ ));
+DESCR("split rows into N groups");
+DATA(insert OID = 3106 ( lag PGNSP PGUID 12 1 0 0 f t f t f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ window_lag _null_ _null_ _null_ ));
+DESCR("fetch the preceding row value");
+DATA(insert OID = 3107 ( lag PGNSP PGUID 12 1 0 0 f t f t f i 2 0 2283 "2283 23" _null_ _null_ _null_ _null_ window_lag_with_offset _null_ _null_ _null_ ));
+DESCR("fetch the Nth preceding row value");
+DATA(insert OID = 3108 ( lag PGNSP PGUID 12 1 0 0 f t f t f i 3 0 2283 "2283 23 2283" _null_ _null_ _null_ _null_ window_lag_with_offset_and_default _null_ _null_ _null_ ));
+DESCR("fetch the Nth preceding row value with default");
+DATA(insert OID = 3109 ( lead PGNSP PGUID 12 1 0 0 f t f t f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ window_lead _null_ _null_ _null_ ));
+DESCR("fetch the following row value");
+DATA(insert OID = 3110 ( lead PGNSP PGUID 12 1 0 0 f t f t f i 2 0 2283 "2283 23" _null_ _null_ _null_ _null_ window_lead_with_offset _null_ _null_ _null_ ));
+DESCR("fetch the Nth following row value");
+DATA(insert OID = 3111 ( lead PGNSP PGUID 12 1 0 0 f t f t f i 3 0 2283 "2283 23 2283" _null_ _null_ _null_ _null_ window_lead_with_offset_and_default _null_ _null_ _null_ ));
+DESCR("fetch the Nth following row value with default");
+DATA(insert OID = 3112 ( first_value PGNSP PGUID 12 1 0 0 f t f t f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ window_first_value _null_ _null_ _null_ ));
+DESCR("fetch the first row value");
+DATA(insert OID = 3113 ( last_value PGNSP PGUID 12 1 0 0 f t f t f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ window_last_value _null_ _null_ _null_ ));
+DESCR("fetch the last row value");
+DATA(insert OID = 3114 ( nth_value PGNSP PGUID 12 1 0 0 f t f t f i 2 0 2283 "2283 23" _null_ _null_ _null_ _null_ window_nth_value _null_ _null_ _null_ ));
+DESCR("fetch the Nth row value");
+
/*
* Symbolic values for provolatile column: these indicate whether the result
diff --git a/src/include/executor/nodeWindowAgg.h b/src/include/executor/nodeWindowAgg.h
new file mode 100644
index 00000000000..e8531037c07
--- /dev/null
+++ b/src/include/executor/nodeWindowAgg.h
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+ *
+ * nodeWindowAgg.h
+ * prototypes for nodeWindowAgg.c
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/executor/nodeWindowAgg.h,v 1.1 2008/12/28 18:54:00 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NODEWINDOWAGG_H
+#define NODEWINDOWAGG_H
+
+#include "nodes/execnodes.h"
+
+extern int ExecCountSlotsWindowAgg(WindowAgg *node);
+extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags);
+extern TupleTableSlot *ExecWindowAgg(WindowAggState *node);
+extern void ExecEndWindowAgg(WindowAggState *node);
+extern void ExecReScanWindowAgg(WindowAggState *node, ExprContext *exprCtxt);
+
+#endif /* NODEWINDOWAGG_H */
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index c348086fbc8..ee95676fe24 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.60 2008/09/03 22:34:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.61 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -516,6 +516,8 @@ extern Oid fmgr_internal_function(const char *proname);
extern Oid get_fn_expr_rettype(FmgrInfo *flinfo);
extern Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum);
extern Oid get_call_expr_argtype(fmNodePtr expr, int argnum);
+extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum);
+extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum);
/*
* Routines in dfmgr.c
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 9aae040019b..258abdee6aa 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.196 2008/11/16 17:34:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.197 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -119,9 +119,12 @@ typedef struct ExprContext
ParamExecData *ecxt_param_exec_vals; /* for PARAM_EXEC params */
ParamListInfo ecxt_param_list_info; /* for other param types */
- /* Values to substitute for Aggref nodes in expression */
- Datum *ecxt_aggvalues; /* precomputed values for Aggref nodes */
- bool *ecxt_aggnulls; /* null flags for Aggref nodes */
+ /*
+ * Values to substitute for Aggref nodes in the expressions of an Agg node,
+ * or for WindowFunc nodes within a WindowAgg node.
+ */
+ Datum *ecxt_aggvalues; /* precomputed values for aggs/windowfuncs */
+ bool *ecxt_aggnulls; /* null flags for aggs/windowfuncs */
/* Value to substitute for CaseTestExpr nodes in expression */
Datum caseValue_datum;
@@ -512,6 +515,17 @@ typedef struct AggrefExprState
} AggrefExprState;
/* ----------------
+ * WindowFuncExprState node
+ * ----------------
+ */
+typedef struct WindowFuncExprState
+{
+ ExprState xprstate;
+ List *args; /* states of argument expressions */
+ int wfuncno; /* ID number for wfunc within its plan node */
+} WindowFuncExprState;
+
+/* ----------------
* ArrayRefExprState node
*
* Note: array types can be fixed-length (typlen > 0), but only when the
@@ -1483,6 +1497,53 @@ typedef struct AggState
} AggState;
/* ----------------
+ * WindowAggState information
+ * ----------------
+ */
+/* these structs are private in nodeWindowAgg.c: */
+typedef struct WindowStatePerFuncData *WindowStatePerFunc;
+typedef struct WindowStatePerAggData *WindowStatePerAgg;
+
+typedef struct WindowAggState
+{
+ ScanState ss; /* its first field is NodeTag */
+
+ /* these fields are filled in by ExecInitExpr: */
+ List *funcs; /* all WindowFunc nodes in targetlist */
+ int numfuncs; /* total number of window functions */
+ int numaggs; /* number that are plain aggregates */
+
+ WindowStatePerFunc perfunc; /* per-window-function information */
+ WindowStatePerAgg peragg; /* per-plain-aggregate information */
+ 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 agg_ptr; /* read pointer # for aggregates */
+ int64 spooled_rows; /* total # of rows in buffer */
+ int64 currentpos; /* position of current row in partition */
+ int64 frametailpos; /* current frame tail position */
+ int64 aggregatedupto; /* rows before this one are aggregated */
+
+ MemoryContext wincontext; /* context for partition-lifespan data */
+ ExprContext *tmpcontext; /* short-term evaluation context */
+
+ bool all_done; /* true if the scan is finished */
+ bool partition_spooled; /* true if all tuples in current partition
+ * have been spooled into tuplestore */
+ bool more_partitions; /* true if there's more partitions after
+ * this one */
+
+ TupleTableSlot *first_part_slot; /* first tuple of current or next
+ * partition */
+
+ /* temporary slots for tuples fetched back from tuplestore */
+ TupleTableSlot *first_peer_slot;
+ TupleTableSlot *temp_slot_1;
+ TupleTableSlot *temp_slot_2;
+} WindowAggState;
+
+/* ----------------
* UniqueState information
*
* Unique nodes are used "on top of" sort nodes to discard
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 7383697f6ce..22649cdc073 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.216 2008/12/19 16:25:19 petere Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.217 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,6 +66,7 @@ typedef enum NodeTag
T_Sort,
T_Group,
T_Agg,
+ T_WindowAgg,
T_Unique,
T_Hash,
T_SetOp,
@@ -103,6 +104,7 @@ typedef enum NodeTag
T_SortState,
T_GroupState,
T_AggState,
+ T_WindowAggState,
T_UniqueState,
T_HashState,
T_SetOpState,
@@ -118,6 +120,7 @@ typedef enum NodeTag
T_Const,
T_Param,
T_Aggref,
+ T_WindowFunc,
T_ArrayRef,
T_FuncExpr,
T_OpExpr,
@@ -164,6 +167,7 @@ typedef enum NodeTag
T_ExprState = 400,
T_GenericExprState,
T_AggrefExprState,
+ T_WindowFuncExprState,
T_ArrayRefExprState,
T_FuncExprState,
T_ScalarArrayOpExprState,
@@ -350,6 +354,7 @@ typedef enum NodeTag
T_ResTarget,
T_TypeCast,
T_SortBy,
+ T_WindowDef,
T_RangeSubselect,
T_RangeFunction,
T_TypeName,
@@ -360,6 +365,7 @@ typedef enum NodeTag
T_OptionDefElem,
T_RangeTblEntry,
T_SortGroupClause,
+ T_WindowClause,
T_FkConstraint,
T_PrivGrantee,
T_FuncWithArgs,
@@ -383,6 +389,7 @@ typedef enum NodeTag
*/
T_TriggerData = 950, /* in commands/trigger.h */
T_ReturnSetInfo, /* in nodes/execnodes.h */
+ T_WindowObjectData, /* private in nodeWindowAgg.c */
T_TIDBitmap /* in nodes/tidbitmap.h */
} NodeTag;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2f22475bf10..43c4452d781 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.384 2008/12/19 16:25:19 petere Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.385 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -120,6 +120,7 @@ typedef struct Query
IntoClause *intoClause; /* target for SELECT INTO / CREATE TABLE AS */
bool hasAggs; /* has aggregates in tlist or havingQual */
+ bool hasWindowFuncs; /* has window functions in tlist */
bool hasSubLinks; /* has subquery SubLink */
bool hasDistinctOn; /* distinctClause is from DISTINCT ON */
bool hasRecursive; /* WITH RECURSIVE was specified */
@@ -137,6 +138,8 @@ typedef struct Query
Node *havingQual; /* qualifications applied to groups */
+ List *windowClause; /* a list of WindowClause's */
+
List *distinctClause; /* a list of SortGroupClause's */
List *sortClause; /* a list of SortGroupClause's */
@@ -269,7 +272,8 @@ typedef struct TypeCast
* agg_star indicates we saw a 'foo(*)' construct, while agg_distinct
* indicates we saw 'foo(DISTINCT ...)'. In either case, the construct
* *must* be an aggregate call. Otherwise, it might be either an
- * aggregate or some other kind of function.
+ * aggregate or some other kind of function. However, if OVER is present
+ * it had better be an aggregate or window function.
*/
typedef struct FuncCall
{
@@ -279,6 +283,7 @@ typedef struct FuncCall
bool agg_star; /* argument was really '*' */
bool agg_distinct; /* arguments were labeled DISTINCT */
bool func_variadic; /* last argument was labeled VARIADIC */
+ struct WindowDef *over; /* OVER clause, if any */
int location; /* token location, or -1 if unknown */
} FuncCall;
@@ -376,6 +381,19 @@ typedef struct SortBy
} SortBy;
/*
+ * WindowDef - raw representation of WINDOW and OVER clauses
+ */
+typedef struct WindowDef
+{
+ NodeTag type;
+ char *name; /* window name (NULL in an OVER clause) */
+ char *refname; /* referenced window name, if any */
+ List *partitionClause; /* PARTITION BY expression list */
+ List *orderClause; /* ORDER BY (list of SortBy) */
+ int location; /* parse location, or -1 if none/unknown */
+} WindowDef;
+
+/*
* RangeSubselect - subquery appearing in a FROM clause
*/
typedef struct RangeSubselect
@@ -662,7 +680,8 @@ typedef struct RangeTblEntry
/*
* SortGroupClause -
- * representation of ORDER BY, GROUP BY, DISTINCT, DISTINCT ON items
+ * representation of ORDER BY, GROUP BY, PARTITION BY,
+ * DISTINCT, DISTINCT ON items
*
* You might think that ORDER BY is only interested in defining ordering,
* and GROUP/DISTINCT are only interested in defining equality. However,
@@ -715,6 +734,31 @@ typedef struct SortGroupClause
} SortGroupClause;
/*
+ * WindowClause -
+ * transformed representation of WINDOW and OVER clauses
+ *
+ * A parsed Query's windowClause list contains these structs. "name" is set
+ * if the clause originally came from WINDOW, and is NULL if it originally
+ * was an OVER clause (but note that we collapse out duplicate OVERs).
+ * partitionClause and orderClause are lists of SortGroupClause structs.
+ * winref is an ID number referenced by WindowFunc nodes; it must be unique
+ * among the members of a Query's windowClause list.
+ * When refname isn't null, the partitionClause is always copied from there;
+ * the orderClause might or might not be copied. (We don't implement
+ * framing clauses yet, but if we did, they are never copied, per spec.)
+ */
+typedef struct WindowClause
+{
+ NodeTag type;
+ char *name; /* window name (NULL in an OVER clause) */
+ char *refname; /* referenced window name, if any */
+ List *partitionClause; /* PARTITION BY list */
+ List *orderClause; /* ORDER BY list */
+ Index winref; /* ID referenced by window functions */
+ bool copiedOrder; /* did we copy orderClause from refname? */
+} WindowClause;
+
+/*
* RowMarkClause -
* representation of FOR UPDATE/SHARE clauses
*
@@ -858,6 +902,7 @@ typedef struct SelectStmt
Node *whereClause; /* WHERE qualification */
List *groupClause; /* GROUP BY clauses */
Node *havingClause; /* HAVING conditional-expression */
+ List *windowClause; /* WINDOW window_name AS (...), ... */
WithClause *withClause; /* WITH clause */
/*
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 16c25fd6d0e..e320fd5fb4c 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.105 2008/10/07 19:27:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.106 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -537,6 +537,21 @@ typedef struct Agg
} Agg;
/* ----------------
+ * window aggregate node
+ * ----------------
+ */
+typedef struct WindowAgg
+{
+ Plan plan;
+ int partNumCols; /* number of columns in partition clause */
+ AttrNumber *partColIdx; /* their indexes in the target list */
+ Oid *partOperators; /* equality operators for partition columns */
+ int ordNumCols; /* number of columns in ordering clause */
+ AttrNumber *ordColIdx; /* their indexes in the target list */
+ Oid *ordOperators; /* equality operators for ordering columns */
+} WindowAgg;
+
+/* ----------------
* unique node
* ----------------
*/
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 2a2ea18520f..36edc80b9a6 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.143 2008/10/06 17:39:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.144 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -222,6 +222,21 @@ typedef struct Aggref
int location; /* token location, or -1 if unknown */
} Aggref;
+/*
+ * WindowFunc
+ */
+typedef struct WindowFunc
+{
+ Expr xpr;
+ Oid winfnoid; /* pg_proc Oid of the function */
+ Oid wintype; /* type Oid of result of the window function */
+ List *args; /* arguments to the window function */
+ Index winref; /* index of associated WindowClause */
+ bool winstar; /* TRUE if argument list was really '*' */
+ bool winagg; /* is function a simple aggregate? */
+ int location; /* token location, or -1 if unknown */
+} WindowFunc;
+
/* ----------------
* ArrayRef: describes an array subscripting operation
*
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 7b67d94700e..ac292692359 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.165 2008/12/01 21:06:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.166 2008/12/28 18:54:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -171,6 +171,7 @@ typedef struct PlannerInfo
* actual pathkeys afterwards */
List *group_pathkeys; /* groupClause pathkeys, if any */
+ List *window_pathkeys; /* pathkeys of bottom window, if any */
List *distinct_pathkeys; /* distinctClause pathkeys, if any */
List *sort_pathkeys; /* sortClause pathkeys, if any */
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 3623aade6a7..f4e668bef30 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.95 2008/10/09 19:27:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.96 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,13 @@ typedef struct
Size transitionSpace; /* for pass-by-ref transition data */
} AggClauseCounts;
+typedef struct
+{
+ int numWindowFuncs; /* total number of WindowFuncs found */
+ Index maxWinRef; /* windowFuncs[] is indexed 0 .. maxWinRef */
+ List **windowFuncs; /* lists of WindowFuncs for each winref */
+} WindowFuncLists;
+
extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
Expr *leftop, Expr *rightop);
@@ -47,8 +54,12 @@ extern Expr *make_ands_explicit(List *andclauses);
extern List *make_ands_implicit(Expr *clause);
extern bool contain_agg_clause(Node *clause);
+extern List *pull_agg_clause(Node *clause);
extern void count_agg_clauses(Node *clause, AggClauseCounts *counts);
+extern bool contain_window_function(Node *clause);
+extern WindowFuncLists *find_window_functions(Node *clause, Index maxWinRef);
+
extern double expression_returns_set_rows(Node *clause);
extern bool contain_subplans(Node *clause);
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 181327caa81..777f7f0fabe 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.93 2008/10/04 21:56:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.94 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -85,6 +85,10 @@ extern void cost_agg(Path *path, PlannerInfo *root,
int numGroupCols, double numGroups,
Cost input_startup_cost, Cost input_total_cost,
double input_tuples);
+extern void cost_windowagg(Path *path, PlannerInfo *root,
+ int numWindowFuncs, int numPartCols, int numOrderCols,
+ Cost input_startup_cost, Cost input_total_cost,
+ double input_tuples);
extern void cost_group(Path *path, PlannerInfo *root,
int numGroupCols, double numGroups,
Cost input_startup_cost, Cost input_total_cost,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 641ebe42fb4..d6f5ff160f6 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.114 2008/10/07 19:27:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.115 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,6 +56,11 @@ extern Agg *make_agg(PlannerInfo *root, List *tlist, List *qual,
int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
long numGroups, int numAggs,
Plan *lefttree);
+extern WindowAgg *make_windowagg(PlannerInfo *root, List *tlist,
+ int numWindowFuncs,
+ int partNumCols, AttrNumber *partColIdx, Oid *partOperators,
+ int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators,
+ Plan *lefttree);
extern Group *make_group(PlannerInfo *root, List *tlist, List *qual,
int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
double numGroups,
diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h
index d2c7f42e05f..dabef328dea 100644
--- a/src/include/optimizer/tlist.h
+++ b/src/include/optimizer/tlist.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.52 2008/08/07 19:35:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.53 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,7 @@ extern TargetEntry *tlist_member(Node *node, List *targetlist);
extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist);
extern List *flatten_tlist(List *tlist);
-extern List *add_to_flat_tlist(List *tlist, List *vars);
+extern List *add_to_flat_tlist(List *tlist, List *exprs);
extern List *get_tlist_exprs(List *tlist, bool includeJunk);
extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK);
diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h
index bf3574e89fc..93b7f674e32 100644
--- a/src/include/parser/parse_agg.h
+++ b/src/include/parser/parse_agg.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* parse_agg.h
- * handle aggregates in parser
+ * handle aggregates and window functions in parser
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_agg.h,v 1.36 2008/01/01 19:45:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_agg.h,v 1.37 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,8 +16,11 @@
#include "parser/parse_node.h"
extern void transformAggregateCall(ParseState *pstate, Aggref *agg);
+extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
+ WindowDef *windef);
extern void parseCheckAggregates(ParseState *pstate, Query *qry);
+extern void parseCheckWindowFuncs(ParseState *pstate, Query *qry);
extern void build_aggregate_fnexprs(Oid *agg_input_types,
int agg_num_inputs,
diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h
index ffea3466b5c..0463e7ae66e 100644
--- a/src/include/parser/parse_clause.h
+++ b/src/include/parser/parse_clause.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.52 2008/08/07 01:11:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.53 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,9 +27,15 @@ extern Node *transformWhereClause(ParseState *pstate, Node *clause,
extern Node *transformLimitClause(ParseState *pstate, Node *clause,
const char *constructName);
extern List *transformGroupClause(ParseState *pstate, List *grouplist,
- List **targetlist, List *sortClause);
+ List **targetlist, List *sortClause,
+ bool isPartition);
extern List *transformSortClause(ParseState *pstate, List *orderlist,
List **targetlist, bool resolveUnknown);
+
+extern List *transformWindowDefinitions(ParseState *pstate,
+ List *windowdefs,
+ List **targetlist);
+
extern List *transformDistinctClause(ParseState *pstate,
List **targetlist, List *sortClause);
extern List *transformDistinctOnClause(ParseState *pstate, List *distinctlist,
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index 8507a4ed7d5..b7023bf8d3d 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.62 2008/12/18 18:20:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.63 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,6 +37,7 @@ typedef enum
FUNCDETAIL_MULTIPLE, /* too many matching functions */
FUNCDETAIL_NORMAL, /* found a matching regular function */
FUNCDETAIL_AGGREGATE, /* found a matching aggregate function */
+ FUNCDETAIL_WINDOWFUNC, /* found a matching window function */
FUNCDETAIL_COERCION /* it's a type coercion request */
} FuncDetailCode;
@@ -44,7 +45,7 @@ typedef enum
extern Node *ParseFuncOrColumn(ParseState *pstate,
List *funcname, List *fargs,
bool agg_star, bool agg_distinct, bool func_variadic,
- bool is_column, int location);
+ WindowDef *over, bool is_column, int location);
extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
int nargs, Oid *argtypes,
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index 8e0d3c201f2..0abe45df32c 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.58 2008/10/08 01:14:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.59 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,6 +57,12 @@
* p_future_ctes: list of CommonTableExprs (WITH items) that are not yet
* visible due to scope rules. This is used to help improve error messages.
*
+ * p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses.
+ * We collect these while transforming expressions and then transform them
+ * afterwards (so that any resjunk tlist items needed for the sort/group
+ * clauses end up at the end of the query tlist). A WindowDef's location in
+ * this list, counting from 1, is the winref number to use to reference it.
+ *
* p_paramtypes: an array of p_numparams type OIDs for $n parameter symbols
* (zeroth entry in array corresponds to $1). If p_variableparams is true, the
* set of param types is not predetermined; in that case, a zero array entry
@@ -77,6 +83,7 @@ typedef struct ParseState
List *p_varnamespace; /* current namespace for columns */
List *p_ctenamespace; /* current namespace for common table exprs */
List *p_future_ctes; /* common table exprs not yet in namespace */
+ List *p_windowdefs; /* raw representations of window clauses */
Oid *p_paramtypes; /* OIDs of types for $n parameter symbols */
int p_numparams; /* allocated size of p_paramtypes[] */
int p_next_resno; /* next targetlist resno to assign */
@@ -84,6 +91,7 @@ typedef struct ParseState
Node *p_value_substitute; /* what to replace VALUE with, if any */
bool p_variableparams;
bool p_hasAggs;
+ bool p_hasWindowFuncs;
bool p_hasSubLinks;
bool p_is_insert;
bool p_is_update;
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 50b4443de0d..9387e71354b 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.47 2008/09/01 20:42:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.48 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,7 +37,9 @@ extern void AddInvertedQual(Query *parsetree, Node *qual);
extern bool contain_aggs_of_level(Node *node, int levelsup);
extern int locate_agg_of_level(Node *node, int levelsup);
+extern int locate_windowfunc(Node *node);
extern bool checkExprHasAggs(Node *node);
+extern bool checkExprHasWindowFuncs(Node *node);
extern bool checkExprHasSubLink(Node *node);
extern Node *ResolveNew(Node *node, int target_varno, int sublevels_up,
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 8a7f10451f0..6d0f5bf13c6 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -49,7 +49,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.72 2008/11/14 00:51:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.73 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -250,7 +250,7 @@ extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
extern Datum makeArrayResult(ArrayBuildState *astate,
MemoryContext rcontext);
extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims,
- int *dims, int *lbs, MemoryContext rcontext);
+ int *dims, int *lbs, MemoryContext rcontext, bool release);
/*
* prototypes for functions defined in arrayutils.c
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index a00415aaa65..65be80c24b4 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.328 2008/12/19 16:25:19 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.329 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -988,6 +988,23 @@ extern Datum uuid_ne(PG_FUNCTION_ARGS);
extern Datum uuid_cmp(PG_FUNCTION_ARGS);
extern Datum uuid_hash(PG_FUNCTION_ARGS);
+/* windowfuncs.c */
+extern Datum window_row_number(PG_FUNCTION_ARGS);
+extern Datum window_rank(PG_FUNCTION_ARGS);
+extern Datum window_dense_rank(PG_FUNCTION_ARGS);
+extern Datum window_percent_rank(PG_FUNCTION_ARGS);
+extern Datum window_cume_dist(PG_FUNCTION_ARGS);
+extern Datum window_ntile(PG_FUNCTION_ARGS);
+extern Datum window_lag(PG_FUNCTION_ARGS);
+extern Datum window_lag_with_offset(PG_FUNCTION_ARGS);
+extern Datum window_lag_with_offset_and_default(PG_FUNCTION_ARGS);
+extern Datum window_lead(PG_FUNCTION_ARGS);
+extern Datum window_lead_with_offset(PG_FUNCTION_ARGS);
+extern Datum window_lead_with_offset_and_default(PG_FUNCTION_ARGS);
+extern Datum window_first_value(PG_FUNCTION_ARGS);
+extern Datum window_last_value(PG_FUNCTION_ARGS);
+extern Datum window_nth_value(PG_FUNCTION_ARGS);
+
/* access/transam/twophase.c */
extern Datum pg_prepared_xact(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/errcodes.h b/src/include/utils/errcodes.h
index baecd7bafcb..4e393c62ac0 100644
--- a/src/include/utils/errcodes.h
+++ b/src/include/utils/errcodes.h
@@ -11,7 +11,7 @@
*
* Copyright (c) 2003-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.26 2008/10/04 21:56:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.27 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -122,6 +122,8 @@
#define ERRCODE_INDICATOR_OVERFLOW MAKE_SQLSTATE('2','2', '0','2','2')
#define ERRCODE_INTERVAL_FIELD_OVERFLOW MAKE_SQLSTATE('2','2', '0','1','5')
#define ERRCODE_INVALID_ARGUMENT_FOR_LOG MAKE_SQLSTATE('2','2', '0','1','E')
+#define ERRCODE_INVALID_ARGUMENT_FOR_NTILE MAKE_SQLSTATE('2','2', '0','1','4')
+#define ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE MAKE_SQLSTATE('2','2', '0','1','6')
#define ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION MAKE_SQLSTATE('2','2', '0', '1', 'F')
#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2', '0', '1', 'G')
#define ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST MAKE_SQLSTATE('2','2', '0','1','8')
@@ -246,6 +248,7 @@
#define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2', '5','0','1')
#define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2', '8','4','6')
#define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2', '8','0','3')
+#define ERRCODE_WINDOWING_ERROR MAKE_SQLSTATE('4','2', 'P','2','0')
#define ERRCODE_INVALID_RECURSION MAKE_SQLSTATE('4','2', 'P','1','9')
#define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2', '8','3','0')
#define ERRCODE_INVALID_NAME MAKE_SQLSTATE('4','2', '6','0','2')
diff --git a/src/include/utils/tuplestore.h b/src/include/utils/tuplestore.h
index 9f9981ff41d..bb9f19cce2c 100644
--- a/src/include/utils/tuplestore.h
+++ b/src/include/utils/tuplestore.h
@@ -24,7 +24,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.26 2008/12/27 17:39:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.27 2008/12/28 18:54:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,6 +68,8 @@ extern void tuplestore_copy_read_pointer(Tuplestorestate *state,
extern void tuplestore_trim(Tuplestorestate *state);
+extern bool tuplestore_in_memory(Tuplestorestate *state);
+
extern bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward,
TupleTableSlot *slot);
extern bool tuplestore_advance(Tuplestorestate *state, bool forward);
diff --git a/src/include/windowapi.h b/src/include/windowapi.h
new file mode 100644
index 00000000000..25ba25fc50a
--- /dev/null
+++ b/src/include/windowapi.h
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * windowapi.h
+ * API for window functions to extract data from their window
+ *
+ * A window function does not receive its arguments in the normal way
+ * (and therefore the concept of strictness is irrelevant). Instead it
+ * receives a "WindowObject", which it can fetch with PG_WINDOW_OBJECT()
+ * (note V1 calling convention must be used). Correct call context can
+ * be tested with WindowObjectIsValid(). Although argument values are
+ * not passed, the call is correctly set up so that PG_NARGS() can be
+ * used and argument type information can be obtained with
+ * get_fn_expr_argtype(), get_fn_expr_arg_stable(), etc.
+ *
+ * Operations on the WindowObject allow the window function to find out
+ * the current row number, total number of rows in the partition, etc
+ * and to evaluate its argument expression(s) at various rows in the
+ * window partition. See the header comments for each WindowObject API
+ * function in nodeWindowAgg.c for details.
+ *
+ *
+ * Portions Copyright (c) 2000-2008, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/windowapi.h,v 1.1 2008/12/28 18:54:00 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef WINDOWAPI_H
+#define WINDOWAPI_H
+
+/* values of "seektype" */
+#define WINDOW_SEEK_CURRENT 0
+#define WINDOW_SEEK_HEAD 1
+#define WINDOW_SEEK_TAIL 2
+
+/* this struct is private in nodeWindowAgg.c */
+typedef struct WindowObjectData *WindowObject;
+
+#define PG_WINDOW_OBJECT() ((WindowObject) fcinfo->context)
+
+#define WindowObjectIsValid(winobj) \
+ ((winobj) != NULL && IsA(winobj, WindowObjectData))
+
+extern void *WinGetPartitionLocalMemory(WindowObject winobj, Size sz);
+
+extern int64 WinGetCurrentPosition(WindowObject winobj);
+extern int64 WinGetPartitionRowCount(WindowObject winobj);
+
+extern void WinSetMarkPosition(WindowObject winobj, int64 markpos);
+
+extern bool WinRowsArePeers(WindowObject winobj, int64 pos1, int64 pos2);
+
+extern Datum WinGetFuncArgInPartition(WindowObject winobj, int argno,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
+extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
+extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno,
+ bool *isnull);
+
+#endif /* WINDOWAPI_H */