summaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-03-12 20:25:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-03-12 20:25:06 +0000
commitfa5e44017a8cea141d1730e695c5cc2051158114 (patch)
treedaafe69293544a73d64701bd38a629d32d0727fc /doc/src
parentde004e44e2cb4c3def05ba3d9f1a6f23e802bea3 (diff)
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.
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/xaggr.sgml17
-rw-r--r--doc/src/sgml/xfunc.sgml20
2 files changed, 31 insertions, 6 deletions
diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml
index d9c41714dff..6a928f7b4f5 100644
--- a/doc/src/sgml/xaggr.sgml
+++ b/doc/src/sgml/xaggr.sgml
@@ -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">
@@ -162,6 +162,21 @@ SELECT attrelid::regclass, array_accum(atttypid)
</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">
command.
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 72772140b36..0f051a36866 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -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: