Annotation Interface Aggregate
An aggregate function in PostgreSQL is defined by using
CREATE AGGREGATE
to specify its name and argument types, along with
at least one "plan" for evaluating it, where the plan specifies at least:
a data type to use for the accumulating state, and a function (here called
"accumulate") called for each row to update the state. If the plan includes
a function "finish", its return type is the return type of the aggregate;
with no "finish" function, the state type is also the aggregate's return
type.
Optionally, a plan can include a "combine" function, which is passed two
instances of the state type and combines them, to allow aggregate evaluation
to be parallelized. The names "accumulate", "combine", and "finish" are not
exactly as used in the PostgreSQL command (those are unpronounceable
abbreviations), but follow the usage in java.util.stream.Collector
,
which should make them natural to Java programmers. PL/Java will generate the
SQL with the unpronounceable names.
If an aggregate function might be used in a window with a moving frame start,
it can be declared with a second plan (movingPlan
) that includes a
"remove" function that may be called, passing values that were earlier
accumulated into the state, to remove them again as the frame start advances
past them. (Java's Collector
has no equivalent of a "remove"
function.) A "remove" function may only be specified (and must be specified)
in a plan given as movingPlan
.
Any function referred to in a plan is specified by its name, optionally
schema-qualified. Its argument types are not specified; they are implied by
those declared for the aggregate itself. An "accumulate" function gets one
argument of the state type, followed by all those given as arguments
.
The same is true of a "remove" function. A "combine" function is passed
two arguments of the state type.
A "finish" function has a first argument of the state type. If the aggregate
is declared with any directArguments
, those follow the state type.
(Declaring directArguments
makes the aggregate an "ordered-set
aggregate", which could additionally have hypothetical=true
to make
it a "hypothetical-set aggregate", for which the PostgreSQL documentation
covers the details.) If polymorphic=true
, the "finish" function's
argument list will end with arguments.length
additional arguments;
they will all be passed as NULL
when the finisher is called, but will
have the right run-time types, which may be necessary to resolve the
finisher's return type, if polymorphic types are involved.
If any of the functions or types mentioned in this declaration are also being
generated into the same deployment descriptor, the CREATE AGGREGATE
generated from this annotation will follow them. Other ordering dependencies,
if necessary, can be explicitly arranged with provides
and
requires
.
While this annotation can generate CREATE AGGREGATE
deployment
commands with the features available in PostgreSQL,
at present there are limits to which aggregate features can be implemented
purely in PL/Java. In particular, PL/Java functions currently have no access
to the PostgreSQL data structures needed for an ordered-set or
hypothetical-set aggregate. Such an aggregate could be implemented by writing
some of its support functions in another procedural language; this annotation
could still be used to automatically generate the declaration.
- Author:
- Chapman Flack
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enum
Declares the effect of thefinish
function in aPlan
.static @interface
Specifies one "plan" for evaluating the aggregate; one must always be specified (asplan
), and a second may be specified (asmovingPlan
). -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionString[]
Names and types of the arguments to be aggregated: the ones passed to theaccumulate
function for each aggregated row.A comment to be associated with the aggregate.String[]
Names and types of the "direct arguments" to an ordered-set or hypothetical-set aggregate (specifying this element is what makes an ordered-set aggregate, which will be a hypothetical-set aggregate ifhypothetical=true
is also supplied).boolean
Specifytrue
in an ordered-set aggregate (one withdirectArguments
specified) to make it a hypothetical-set aggregate.The<implementor name>
to be used around SQL code generated for this aggregate.An optionalPlan
that may be more efficient for evaluating this aggregate in a moving-window context.String[]
Name for this aggregate.Parallel-safety declaration for this aggregate; PostgreSQL's planner will consult this only, not the declarations on the individual supporting functions.ThePlan
normally to be used for evaluating this aggregate, except possibly in a moving-window context ifmovingPlan
is also supplied.String[]
One or more arbitrary labels that will be considered 'provided' by the object carrying this annotation.String[]
One or more arbitrary labels that will be considered 'required' by the object carrying this annotation.String[]
Name of an operator (declared as either the less-than or greater-than strategy member of abtree
operator class) such that the result of this aggregate is the same as the first result fromORDER BY
over the aggregated values, using this operator.boolean[]
Whether the aggregate has a variadic last argument.
-
Element Details
-
name
String[] nameName for this aggregate.May be specified in explicit
{"schema","localname"}
form, or as a single string that will be leniently parsed as an optionally schema-qualified name. In the explicit form,""
as the schema will make the name explicitly unqualified (in case the local name might contain a dot and be misread as a qualified name).When this annotation is not placed on a method, there is no default, and a name must be supplied. When the annotation is on a method (which can be either the
accumulate
or thefinish
function for the aggregate), the default name will be the same as the SQL name given for the function. That is typically possible because the parameter signature for the aggregate function will not be the same as either theaccumulate
or thefinish
function. The exception is if the annotation is on thefinish
function and the aggregate has exactly one parameter of the same type as the state; in that case another name must be given here.- Default:
{}
-
arguments
String[] argumentsNames and types of the arguments to be aggregated: the ones passed to theaccumulate
function for each aggregated row.Each element is a name and a type specification, separated by whitespace. An element that begins with whitespace declares a parameter with no name, only a type. The name is an ordinary SQL identifier; if it would be quoted in SQL, naturally each double-quote must be represented as
\"
in Java.When this annotation does not appear on a method, there is no default, and arguments must be declared here. If the annotation appears on a method supplying the
accumulate
function, this element can be omitted, and the arguments will be those of the function (excepting the first one, which corresponds to the state).- Default:
{}
-
directArguments
String[] directArgumentsNames and types of the "direct arguments" to an ordered-set or hypothetical-set aggregate (specifying this element is what makes an ordered-set aggregate, which will be a hypothetical-set aggregate ifhypothetical=true
is also supplied).Specified as for
arguments
. The direct arguments are not passed to theaccumulate
function for each aggregated row; they are only passed to thefinish
function when producing the result.- Default:
{}
-
hypothetical
boolean hypotheticalSpecifytrue
in an ordered-set aggregate (one withdirectArguments
specified) to make it a hypothetical-set aggregate.When
true
, thedirectArguments
list must be at least as long asarguments
, and its lastarguments.length
types must matcharguments
one-to-one. When thefinish
function is called, those last direct arguments will carry the caller-supplied values for the "hypothetical" row.- Default:
false
-
variadic
boolean[] variadicWhether the aggregate has a variadic last argument.Specify as a single boolean,
variadic=true
, to declare an ordinary aggregate variadic. The last type of its declaredarguments
must then be either an array type, orpg_catalog."any"
The form
variadic={boolean,boolean}
is for an ordered-set aggregate, which has both a list ofdirectArguments
(the first boolean) and its aggregatedarguments
(the second). For an ordered-set aggregate,"any"
is the only allowed type for a variadic argument.When also
hypothetical
is true, the requirement that thedirectArguments
have a tail matching thearguments
implies that the two lists must both or neither be variadic.- Default:
{}
-
plan
Aggregate.Plan[] planThePlan
normally to be used for evaluating this aggregate, except possibly in a moving-window context ifmovingPlan
is also supplied.Though declared as an array, only one plan is allowed here. It may not name a
remove
function; only amovingPlan
can do that. This plan can be omitted only if the@Aggregate
annotation appears on a Java method intended as theaccumulate
function and the rest of the plan is all to be inferred or defaulted.- Default:
{}
-
movingPlan
Aggregate.Plan[] movingPlanAn optionalPlan
that may be more efficient for evaluating this aggregate in a moving-window context.Though declared as an array, only one plan is allowed here. It must name a
remove
function.A
movingPlan
may not haveserialize
/deserialize
functions; onlyplan
can have those.- Default:
{}
-
parallel
Function.Parallel parallelParallel-safety declaration for this aggregate; PostgreSQL's planner will consult this only, not the declarations on the individual supporting functions.See
Function.parallel
for the implications. In PL/Java, any setting other thanUNSAFE
should be considered experimental.- Default:
UNSAFE
-
sortOperator
String[] sortOperatorName of an operator (declared as either the less-than or greater-than strategy member of abtree
operator class) such that the result of this aggregate is the same as the first result fromORDER BY
over the aggregated values, using this operator.May be specified in explicit
{"schema","localname"}
form, or as a single string that will be leniently parsed as an optionally schema-qualified name. In the explicit form,""
as the schema will make the name explicitly unqualified. The operator will be assumed to have two operands of the same type as the argument to the aggregate (which must have exactly one aggregated argument, and no direct arguments). The operator's membership in abtree
operator class is not (currently) checked at compile time, but if it does not hold at run time, the optimization will not be used.- Default:
{}
-
provides
String[] providesOne or more arbitrary labels that will be considered 'provided' by the object carrying this annotation. The deployment descriptor will be generated in such an order that other objects that 'require' labels 'provided' by this come later in the output for install actions, and earlier for remove actions.- Default:
{}
-
requires
String[] requiresOne or more arbitrary labels that will be considered 'required' by the object carrying this annotation. The deployment descriptor will be generated in such an order that other objects that 'provide' labels 'required' by this come earlier in the output for install actions, and later for remove actions.- Default:
{}
-
implementor
String implementorThe<implementor name>
to be used around SQL code generated for this aggregate. Defaults toPostgreSQL
. Set explicitly to""
to emit code not wrapped in an<implementor block>
.- Default:
""
-
comment
String commentA comment to be associated with the aggregate. The default is no comment if the annotation does not appear on a method, or the first sentence of the method's Javadoc comment, if any, if it does.- Default:
""
-