mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Adjust the API for aggregate function calls so that a C-coded function
can tell whether it is being used as an aggregate or not. This allows such a function to avoid re-pallocing a pass-by-reference transition value; normally it would be unsafe for a function to scribble on an input, but in the aggregate case it's safe to reuse the old transition value. Make int8inc() do this. This gets a useful improvement in the speed of COUNT(*), at least on narrow tables (it seems to be swamped by I/O when the table rows are wide). Per a discussion in early December with Neil Conway. I also fixed int_aggregate.c to check this, thereby turning it into something approaching a supportable technique instead of being a crude hack.
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/xaggr.sgml,v 1.26 2005/01/22 22:56:36 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/xaggr.sgml,v 1.27 2005/03/12 20:25:06 tgl Exp $
|
||||
-->
|
||||
|
||||
<sect1 id="xaggr">
|
||||
@ -161,6 +161,21 @@ SELECT attrelid::regclass, array_accum(atttypid)
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A function written in C can detect that it is being called as an
|
||||
aggregate transition or final function by seeing if it was passed
|
||||
an <structname>AggState</> node as the function call <quote>context</>,
|
||||
for example by
|
||||
<programlisting>
|
||||
if (fcinfo->context && IsA(fcinfo->context, AggState))
|
||||
</programlisting>
|
||||
One reason for checking this is that when it is true, the left input
|
||||
must be a temporary transition value and can therefore safely be modified
|
||||
in-place rather than allocating a new copy. (This is the <emphasis>only</>
|
||||
case where it is safe for a function to modify a pass-by-reference input.)
|
||||
See <literal>int8inc()></> for an example.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For further details see the
|
||||
<xref linkend="sql-createaggregate" endterm="sql-createaggregate-title">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.99 2005/02/21 06:12:14 neilc Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.100 2005/03/12 20:25:06 tgl Exp $
|
||||
-->
|
||||
|
||||
<sect1 id="xfunc">
|
||||
@ -1188,10 +1188,10 @@ typedef struct
|
||||
them in and out of <productname>PostgreSQL</productname> functions.
|
||||
To return a value of such a type, allocate the right amount of
|
||||
memory with <literal>palloc</literal>, fill in the allocated memory,
|
||||
and return a pointer to it. (You can also return an input value
|
||||
that has the same type as the return value directly by returning
|
||||
the pointer to the input value. <emphasis>Never</> modify the
|
||||
contents of a pass-by-reference input value, however.)
|
||||
and return a pointer to it. (Also, if you just want to return the
|
||||
same value as one of your input arguments that's of the same data type,
|
||||
you can skip the extra <literal>palloc</literal> and just return the
|
||||
pointer to the input value.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1205,6 +1205,16 @@ typedef struct
|
||||
itself.
|
||||
</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
<emphasis>Never</> modify the contents of a pass-by-reference input
|
||||
value. If you do so you are likely to corrupt on-disk data, since
|
||||
the pointer you are given may well point directly into a disk buffer.
|
||||
The sole exception to this rule is explained in
|
||||
<xref linkend="xaggr">.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<para>
|
||||
As an example, we can define the type <type>text</type> as
|
||||
follows:
|
||||
|
Reference in New Issue
Block a user