[ , MFINALFUNC_EXTRA ]
[ , MINITCOND = <replaceable class="PARAMETER">minitial_condition</replaceable> ]
[ , SORTOP = <replaceable class="PARAMETER">sort_operator</replaceable> ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
)
CREATE AGGREGATE <replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">arg_data_type</replaceable> [ , ... ] ]
[ , SERIALTYPE = <replaceable class="PARAMETER">serialtype</replaceable> ]
[ , INITCOND = <replaceable class="PARAMETER">initial_condition</replaceable> ]
[ , HYPOTHETICAL ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+
)
<phrase>or the old syntax</phrase>
Currently, ordered-set aggregates do not need to support
moving-aggregate mode, since they cannot be used as window functions.
</para>
+
+ <para>
+ The meaning of <literal>PARALLEL SAFE</>, <literal>PARALLEL RESTRICTED</>,
+ and <literal>PARALLEL UNSAFE</> is the same as for
+ <xref linkend="sql-createfunction">.
+ </para>
</refsect1>
<refsect1>
Oid aggmTransType,
int32 aggmTransSpace,
const char *agginitval,
- const char *aggminitval)
+ const char *aggminitval,
+ char proparallel)
{
Relation aggdesc;
HeapTuple tup;
false, /* isStrict (not needed for agg) */
PROVOLATILE_IMMUTABLE, /* volatility (not
* needed for agg) */
- PROPARALLEL_UNSAFE,
+ proparallel,
parameterTypes, /* paramTypes */
allParameterTypes, /* allParamTypes */
parameterModes, /* parameterModes */
int32 mtransSpace = 0;
char *initval = NULL;
char *minitval = NULL;
+ char *parallel = NULL;
int numArgs;
int numDirectArgs = 0;
oidvector *parameterTypes;
Oid mtransTypeId = InvalidOid;
char transTypeType;
char mtransTypeType = 0;
+ char proparallel = PROPARALLEL_UNSAFE;
ListCell *pl;
/* Convert list of names to a name and namespace */
initval = defGetString(defel);
else if (pg_strcasecmp(defel->defname, "minitcond") == 0)
minitval = defGetString(defel);
+ else if (pg_strcasecmp(defel->defname, "parallel") == 0)
+ parallel = defGetString(defel);
else
ereport(WARNING,
(errcode(ERRCODE_SYNTAX_ERROR),
(void) OidInputFunctionCall(typinput, minitval, typioparam, -1);
}
+ if (parallel)
+ {
+ if (pg_strcasecmp(parallel, "safe") == 0)
+ proparallel = PROPARALLEL_SAFE;
+ else if (pg_strcasecmp(parallel, "restricted") == 0)
+ proparallel = PROPARALLEL_RESTRICTED;
+ else if (pg_strcasecmp(parallel, "unsafe") == 0)
+ proparallel = PROPARALLEL_UNSAFE;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
+ }
+
/*
* Most of the argument-checking is done inside of AggregateCreate
*/
mtransTypeId, /* transition data type */
mtransSpace, /* transition space */
initval, /* initial condition */
- minitval); /* initial condition */
+ minitval, /* initial condition */
+ proparallel); /* parallel safe? */
}
else
{
ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("parallel option \"%s\" not recognized",
- str)));
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
return PROPARALLEL_UNSAFE; /* keep compiler quiet */
}
}
if (parallel_too_dangerous(func_parallel(expr->funcid), context))
return true;
}
+ else if (IsA(node, Aggref))
+ {
+ Aggref *aggref = (Aggref *) node;
+
+ if (parallel_too_dangerous(func_parallel(aggref->aggfnoid), context))
+ return true;
+ }
else if (IsA(node, OpExpr))
{
OpExpr *expr = (OpExpr *) node;
Oid aggmTransType,
int32 aggmTransSpace,
const char *agginitval,
- const char *aggminitval);
+ const char *aggminitval,
+ char proparallel);
#endif /* PG_AGGREGATE_H */
-- zero-argument aggregate
CREATE AGGREGATE newcnt (*) (
sfunc = int8inc, stype = int8,
- initcond = '0'
+ initcond = '0', parallel = safe
);
--- old-style spelling of same
+-- old-style spelling of same (except without parallel-safe; that's too new)
CREATE AGGREGATE oldcnt (
sfunc = int8inc, basetype = 'ANY', stype = int8,
initcond = '0'
(1 row)
DROP AGGREGATE myavg (numeric);
+-- invalid: bad parallel-safety marking
+CREATE AGGREGATE mysum (int)
+(
+ stype = int,
+ sfunc = int4pl,
+ parallel = pear
+);
+ERROR: parameter "parallel" must be SAFE, RESTRICTED, or UNSAFE
-- invalid: nonstrict inverse with strict forward function
CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS
$$ SELECT $1 - $2; $$
-- zero-argument aggregate
CREATE AGGREGATE newcnt (*) (
sfunc = int8inc, stype = int8,
- initcond = '0'
+ initcond = '0', parallel = safe
);
--- old-style spelling of same
+-- old-style spelling of same (except without parallel-safe; that's too new)
CREATE AGGREGATE oldcnt (
sfunc = int8inc, basetype = 'ANY', stype = int8,
initcond = '0'
DROP AGGREGATE myavg (numeric);
+-- invalid: bad parallel-safety marking
+CREATE AGGREGATE mysum (int)
+(
+ stype = int,
+ sfunc = int4pl,
+ parallel = pear
+);
+
-- invalid: nonstrict inverse with strict forward function
CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS