1
0
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:
Tom Lane
2005-03-12 20:25:06 +00:00
parent de004e44e2
commit fa5e44017a
6 changed files with 159 additions and 70 deletions

View File

@ -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 &amp;&amp; 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">

View File

@ -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: