diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-12-31 00:08:39 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-12-31 00:08:39 +0000 |
commit | 8e8854daa2b4b3ef9e3fc1a56c79608a70018058 (patch) | |
tree | a6c4cf4b43acc764a38071843c10dc3edb3ca32e /src/backend/parser/parse_agg.c | |
parent | 0fb9be7acfb31ba38c1bbdd7883d5d03f6e261e5 (diff) | |
download | postgresql-8e8854daa2b4b3ef9e3fc1a56c79608a70018058.tar.gz postgresql-8e8854daa2b4b3ef9e3fc1a56c79608a70018058.zip |
Add some basic support for window frame clauses to the window-functions
patch. This includes the ability to force the frame to cover the whole
partition, and the ability to make the frame end exactly on the current row
rather than its last ORDER BY peer. Supporting any more of the full SQL
frame-clause syntax will require nontrivial hacking on the window aggregate
code, so it'll have to wait for 8.5 or beyond.
Diffstat (limited to 'src/backend/parser/parse_agg.c')
-rw-r--r-- | src/backend/parser/parse_agg.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 6dba470e39f..23913c62914 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.85 2008/12/28 18:53:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.86 2008/12/31 00:08:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -123,25 +123,27 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, locate_windowfunc((Node *) wfunc->args)))); /* - * If the OVER clause just specifies a reference name, find that + * If the OVER clause just specifies a window name, find that * WINDOW clause (which had better be present). Otherwise, try to * match all the properties of the OVER clause, and make a new entry * in the p_windowdefs list if no luck. */ - Assert(!windef->name); - if (windef->refname && - windef->partitionClause == NIL && - windef->orderClause == NIL) + if (windef->name) { Index winref = 0; ListCell *lc; + Assert(windef->refname == NULL && + windef->partitionClause == NIL && + windef->orderClause == NIL && + windef->frameOptions == FRAMEOPTION_DEFAULTS); + foreach(lc, pstate->p_windowdefs) { WindowDef *refwin = (WindowDef *) lfirst(lc); winref++; - if (refwin->name && strcmp(refwin->name, windef->refname) == 0) + if (refwin->name && strcmp(refwin->name, windef->name) == 0) { wfunc->winref = winref; break; @@ -150,7 +152,7 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, if (lc == NULL) /* didn't find it? */ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("window \"%s\" does not exist", windef->refname), + errmsg("window \"%s\" does not exist", windef->name), parser_errposition(pstate, windef->location))); } else @@ -164,14 +166,15 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, winref++; if (refwin->refname && windef->refname && - strcmp(refwin->name, windef->refname) == 0) + strcmp(refwin->refname, windef->refname) == 0) /* matched on refname */ ; else if (!refwin->refname && !windef->refname) /* matched, no refname */ ; else continue; if (equal(refwin->partitionClause, windef->partitionClause) && - equal(refwin->orderClause, windef->orderClause)) + equal(refwin->orderClause, windef->orderClause) && + refwin->frameOptions == windef->frameOptions) { /* found a duplicate window specification */ wfunc->winref = winref; |