<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.83 2008/12/18 18:20:33 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.84 2008/12/31 02:25:03 tgl Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
[ RETURNS <replaceable class="parameter">rettype</replaceable>
| RETURNS TABLE ( <replaceable class="parameter">colname</replaceable> <replaceable class="parameter">coltype</replaceable> [, ...] ) ]
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
+ | WINDOW
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
</varlistentry>
<varlistentry>
+ <term><literal>WINDOW</literal></term>
+
+ <listitem>
+ <para>
+ <literal>WINDOW</literal> indicates that the function is a
+ <firstterm>window function</> rather than a plain function.
+ This is currently only useful for functions written in C.
+ The <literal>WINDOW</> attribute cannot be changed when
+ replacing an existing function definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>IMMUTABLE</literal></term>
<term><literal>STABLE</literal></term>
<term><literal>VOLATILE</literal></term>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.99 2008/12/18 18:20:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.100 2008/12/31 02:25:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
"aggregate_dummy", /* placeholder proc */
NULL, /* probin */
true, /* isAgg */
+ false, /* isWindowFunc */
false, /* security invoker (currently not
* definable for agg) */
false, /* isStrict (not needed for agg) */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.158 2008/12/28 18:53:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.159 2008/12/31 02:25:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*
* Note: allParameterTypes, parameterModes, parameterNames, and proconfig
* are either arrays of the proper types or NULL. We declare them Datum,
- * not "ArrayType *", to avoid importing array.h into pg_proc.h.
+ * not "ArrayType *", to avoid importing array.h into pg_proc_fn.h.
* ----------------------------------------------------------------
*/
Oid
const char *prosrc,
const char *probin,
bool isAgg,
+ bool isWindowFunc,
bool security_definer,
bool isStrict,
char volatility,
float4 prorows)
{
Oid retval;
- /* XXX we don't currently have a way to make new window functions */
- bool isWindowFunc = false;
int parameterCount;
int allParamCount;
Oid *allParams;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.104 2008/12/28 18:53:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.105 2008/12/31 02:25:03 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
compute_attributes_sql_style(List *options,
List **as,
char **language,
+ bool *windowfunc_p,
char *volatility_p,
bool *strict_p,
bool *security_definer,
ListCell *option;
DefElem *as_item = NULL;
DefElem *language_item = NULL;
+ DefElem *windowfunc_item = NULL;
DefElem *volatility_item = NULL;
DefElem *strict_item = NULL;
DefElem *security_item = NULL;
errmsg("conflicting or redundant options")));
language_item = defel;
}
+ else if (strcmp(defel->defname, "window") == 0)
+ {
+ if (windowfunc_item)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ windowfunc_item = defel;
+ }
else if (compute_common_attribute(defel,
&volatility_item,
&strict_item,
}
/* process optional items */
+ if (windowfunc_item)
+ *windowfunc_p = intVal(windowfunc_item->arg);
if (volatility_item)
*volatility_p = interpret_func_volatility(volatility_item);
if (strict_item)
ArrayType *parameterNames;
List *parameterDefaults;
Oid requiredResultType;
- bool isStrict,
+ bool isWindowFunc,
+ isStrict,
security;
char volatility;
ArrayType *proconfig;
get_namespace_name(namespaceId));
/* default attributes */
+ isWindowFunc = false;
isStrict = false;
security = false;
volatility = PROVOLATILE_VOLATILE;
/* override attributes from explicit list */
compute_attributes_sql_style(stmt->options,
&as_clause, &language,
- &volatility, &isStrict, &security,
+ &isWindowFunc, &volatility,
+ &isStrict, &security,
&proconfig, &procost, &prorows);
/* Convert language name to canonical case */
prosrc_str, /* converted to text later */
probin_str, /* converted to text later */
false, /* not an aggregate */
+ isWindowFunc,
security,
isStrict,
volatility,
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.82 2008/12/18 18:20:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.83 2008/12/31 02:25:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
pltemplate->tmplhandler,
pltemplate->tmpllibrary,
false, /* isAgg */
+ false, /* isWindowFunc */
false, /* security_definer */
false, /* isStrict */
PROVOLATILE_VOLATILE,
pltemplate->tmplvalidator,
pltemplate->tmpllibrary,
false, /* isAgg */
+ false, /* isWindowFunc */
false, /* security_definer */
false, /* isStrict */
PROVOLATILE_VOLATILE,
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.649 2008/12/31 00:08:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.650 2008/12/31 02:25:04 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
{
$$ = makeDefElem("language", (Node *)makeString($2));
}
+ | WINDOW
+ {
+ $$ = makeDefElem("window", (Node *)makeInteger(TRUE));
+ }
| common_func_opt_item
{
$$ = $1;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.292 2008/12/31 00:08:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.293 2008/12/31 02:25:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Emit some miscellaneous options on one line */
oldlen = buf.len;
+ if (proc->proiswindow)
+ appendStringInfoString(&buf, " WINDOW");
switch (proc->provolatile)
{
case PROVOLATILE_IMMUTABLE:
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.509 2008/12/19 16:25:18 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.510 2008/12/31 02:25:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
char *proallargtypes;
char *proargmodes;
char *proargnames;
+ char *proiswindow;
char *provolatile;
char *proisstrict;
char *prosecdef;
"pg_catalog.pg_get_function_arguments(oid) as funcargs, "
"pg_catalog.pg_get_function_identity_arguments(oid) as funciargs, "
"pg_catalog.pg_get_function_result(oid) as funcresult, "
- "provolatile, proisstrict, prosecdef, "
+ "proiswindow, provolatile, proisstrict, prosecdef, "
"proconfig, procost, prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
"FROM pg_catalog.pg_proc "
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
"proallargtypes, proargmodes, proargnames, "
+ "false as proiswindow, "
"provolatile, proisstrict, prosecdef, "
"proconfig, procost, prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
"proallargtypes, proargmodes, proargnames, "
+ "false as proiswindow, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
"null as proallargtypes, "
"null as proargmodes, "
"proargnames, "
+ "false as proiswindow, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
"null as proallargtypes, "
"null as proargmodes, "
"null as proargnames, "
+ "false as proiswindow, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
"null as proallargtypes, "
"null as proargmodes, "
"null as proargnames, "
+ "false as proiswindow, "
"case when proiscachable then 'i' else 'v' end as provolatile, "
"proisstrict, "
- "'f'::boolean as prosecdef, "
+ "false as prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc "
"null as proallargtypes, "
"null as proargmodes, "
"null as proargnames, "
+ "false as proiswindow, "
"case when proiscachable then 'i' else 'v' end as provolatile, "
- "'f'::boolean as proisstrict, "
- "'f'::boolean as prosecdef, "
+ "false as proisstrict, "
+ "false as prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc "
proargnames = PQgetvalue(res, 0, PQfnumber(res, "proargnames"));
funcargs = funciargs = funcresult = NULL;
}
+ proiswindow = PQgetvalue(res, 0, PQfnumber(res, "proiswindow"));
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
}
appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
+
+ if (proiswindow[0] == 't')
+ appendPQExpBuffer(q, " WINDOW");
+
if (provolatile[0] != PROVOLATILE_VOLATILE)
{
if (provolatile[0] == PROVOLATILE_IMMUTABLE)
* 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_fn.h,v 1.4 2008/12/18 18:20:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc_fn.h,v 1.5 2008/12/31 02:25:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
const char *prosrc,
const char *probin,
bool isAgg,
+ bool isWindowFunc,
bool security_definer,
bool isStrict,
char volatility,