Annotation Type Aggregate


@Documented
@Target({TYPE,METHOD})
@Repeatable(Container.class)
@Retention(CLASS)
public @interface Aggregate
Declares a PostgreSQL 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 Classes
    Modifier and Type Class Description
    static class  Aggregate.FinishEffect
    Declares the effect of the finish function in a Plan.
    static interface  Aggregate.Plan
    Specifies one "plan" for evaluating the aggregate; one must always be specified (as plan), and a second may be specified (as movingPlan).
  • Optional Element Summary

    Optional Elements
    Modifier and Type Optional Element Description
    String[] arguments
    Names and types of the arguments to be aggregated: the ones passed to the accumulate function for each aggregated row.
    String comment
    A comment to be associated with the aggregate.
    String[] directArguments
    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 if hypothetical=true is also supplied).
    boolean hypothetical
    Specify true in an ordered-set aggregate (one with directArguments specified) to make it a hypothetical-set aggregate.
    String implementor
    The <implementor name> to be used around SQL code generated for this aggregate.
    Aggregate.Plan[] movingPlan
    An optional Plan that may be more efficient for evaluating this aggregate in a moving-window context.
    String[] name
    Name for this aggregate.
    Function.Parallel parallel
    Parallel-safety declaration for this aggregate; PostgreSQL's planner will consult this only, not the declarations on the individual supporting functions.
    Aggregate.Plan[] plan
    The Plan normally to be used for evaluating this aggregate, except possibly in a moving-window context if movingPlan is also supplied.
    String[] provides
    One or more arbitrary labels that will be considered 'provided' by the object carrying this annotation.
    String[] requires
    One or more arbitrary labels that will be considered 'required' by the object carrying this annotation.
    String[] sortOperator
    Name of an operator (declared as either the less-than or greater-than strategy member of a btree operator class) such that the result of this aggregate is the same as the first result from ORDER BY over the aggregated values, using this operator.
    boolean[] variadic
    Whether the aggregate has a variadic last argument.
  • Element Details

    • name

      String[] name
      Name 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 the finish 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 the accumulate or the finish function. The exception is if the annotation is on the finish 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[] arguments
      Names and types of the arguments to be aggregated: the ones passed to the accumulate 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[] directArguments
      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 if hypothetical=true is also supplied).

      Specified as for arguments. The direct arguments are not passed to the accumulate function for each aggregated row; they are only passed to the finish function when producing the result.

      Default:
      {}
    • hypothetical

      boolean hypothetical
      Specify true in an ordered-set aggregate (one with directArguments specified) to make it a hypothetical-set aggregate.

      When true, the directArguments list must be at least as long as arguments, and its last arguments.length types must match arguments one-to-one. When the finish function is called, those last direct arguments will carry the caller-supplied values for the "hypothetical" row.

      Default:
      false
    • variadic

      boolean[] variadic
      Whether 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 declared arguments must then be either an array type, or pg_catalog."any"

      The form variadic={boolean,boolean} is for an ordered-set aggregate, which has both a list of directArguments (the first boolean) and its aggregated arguments (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 the directArguments have a tail matching the arguments implies that the two lists must both or neither be variadic.

      Default:
      {}
    • plan

      The Plan normally to be used for evaluating this aggregate, except possibly in a moving-window context if movingPlan is also supplied.

      Though declared as an array, only one plan is allowed here. It may not name a remove function; only a movingPlan can do that. This plan can be omitted only if the @Aggregate annotation appears on a Java method intended as the accumulate function and the rest of the plan is all to be inferred or defaulted.

      Default:
      {}
    • movingPlan

      Aggregate.Plan[] movingPlan
      An optional Plan 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 have serialize/deserialize functions; only plan can have those.

      Default:
      {}
    • parallel

      Parallel-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 than UNSAFE should be considered experimental.

      Default:
      UNSAFE
    • sortOperator

      String[] sortOperator
      Name of an operator (declared as either the less-than or greater-than strategy member of a btree operator class) such that the result of this aggregate is the same as the first result from ORDER 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 a btree 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[] provides
      One 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[] requires
      One 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 implementor
      The <implementor name> to be used around SQL code generated for this aggregate. Defaults to PostgreSQL. Set explicitly to "" to emit code not wrapped in an <implementor block>.
      Default:
      ""
    • comment

      String comment
      A 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:
      ""