diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-03-12 20:25:06 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-03-12 20:25:06 +0000 |
commit | fa5e44017a8cea141d1730e695c5cc2051158114 (patch) | |
tree | daafe69293544a73d64701bd38a629d32d0727fc /doc/src | |
parent | de004e44e2cb4c3def05ba3d9f1a6f23e802bea3 (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.sgml | 17 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 20 |
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 && 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: |