Re: array_accum aggregate - Mailing list pgsql-patches

From Neil Conway
Subject Re: array_accum aggregate
Date
Msg-id 1160673737.5120.12.camel@localhost.localdomain
Whole thread Raw
In response to array_accum aggregate  (Stephen Frost <sfrost@snowman.net>)
Responses Re: array_accum aggregate  (Stephen Frost <sfrost@snowman.net>)
List pgsql-patches
On Wed, 2006-10-11 at 00:51 -0400, Stephen Frost wrote:
> An array_accum aggregate has existed in the documentation for quite
> some time using the inefficient (for larger arrays) array_append
> routine.

My vague recollection is that array_accum() is only defined in the
documentation because there was some debate about how it ought to behave
in some corner cases. I can't recall the details, but it was discussed
when array_accum() was originally proposed by Joe. Does anyone remember?

Minor comments on the patch:

> *** 132,138 ****
>   </programlisting>
>
>      Here, the actual state type for any aggregate call is the array type
> !    having the actual input type as elements.
>     </para>
>
>     <para>
> --- 132,141 ----
>   </programlisting>
>
>      Here, the actual state type for any aggregate call is the array type
> !    having the actual input type as elements.  Note: array_accum() is now
> !    a built-in aggregate which uses a much more efficient mechanism than
> !    that which is provided by array_append, prior users of array_accum()
> !    may be pleasantly suprised at the marked improvment for larger arrays.
>     </para>

Not worth documenting, I think.

> *** 15,20 ****
> --- 15,22 ----
>   #include "utils/array.h"
>   #include "utils/builtins.h"
>   #include "utils/lsyscache.h"
> + #include "utils/memutils.h"
> + #include "nodes/execnodes.h"

Include directives should be sorted roughly alphabetically, with the
exception of postgres.h and system headers.

> + /* Structure, used by aaccum_sfunc and aaccum_ffunc to
> +  * implement the array_accum() aggregate, for storing
> +  * pointers to the ArrayBuildState for the array we are
> +  * building and the MemoryContext in which it is being
> +  * built.  Note that this structure is
> +  * considered an 'anyarray' externally, which is a
> +  * variable-length datatype, and therefore
> +  * must open with an int32 defining the length. */

Gross.

> +     /* Make sure we are being called in an aggregate. */
> +     if (!fcinfo->context || !IsA(fcinfo->context, AggState))
> +         ereport(ERROR,
> +                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
> +                  errmsg("Can not call aaccum_sfunc as a non-aggregate"),
> +                  errhint("Use the array_accum aggregate")));

Per the error message style guidelines, errmsg() should begin with a
lowercase letter and errhint() should be a complete sentence (so it
needs punctuation, for example).

> + Datum
> + aaccum_ffunc(PG_FUNCTION_ARGS)
> + {
> +     aaccum_info        *ainfo;
> +
> +     /* Check if we are passed in a NULL */
> +     if (PG_ARGISNULL(0)) PG_RETURN_ARRAYTYPE_P(NULL);

There is no guarantee why SQL NULL and PG_RETURN_XYZ(NULL) refer to the
same thing -- use PG_RETURN_NULL() to return a SQL NULL value, or just
make the function strict.

-Neil



pgsql-patches by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: [GENERAL] ISO week dates
Next
From: Stephen Frost
Date:
Subject: Re: array_accum aggregate