aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-04-11 20:00:18 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-04-11 20:00:18 +0000
commit902a6a0a4bc62d619a5ccd1ef0ff7fb3a5d897f1 (patch)
treec5cc85818d8a3ffae03a23bacd3e679945a41dbd /doc/src
parent3f6299df6c7d905bdef44eb3a4b19f248ebc14dc (diff)
downloadpostgresql-902a6a0a4bc62d619a5ccd1ef0ff7fb3a5d897f1.tar.gz
postgresql-902a6a0a4bc62d619a5ccd1ef0ff7fb3a5d897f1.zip
Restructure representation of aggregate functions so that they have pg_proc
entries, per pghackers discussion. This fixes aggregates to live in namespaces, and also simplifies/speeds up lookup in parse_func.c. Also, add a 'proimplicit' flag to pg_proc that controls whether a type coercion function may be invoked implicitly, or only explicitly. The current settings of these flags are more permissive than I would like, but we will need to debate and refine the behavior; for now, I avoided breaking regression tests as much as I could.
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/catalogs.sgml77
-rw-r--r--doc/src/sgml/ref/create_aggregate.sgml7
-rw-r--r--doc/src/sgml/ref/create_function.sgml66
3 files changed, 102 insertions, 48 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index ba9c9b15e79..03809d69e42 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,6 +1,6 @@
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
- $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.40 2002/04/05 00:31:22 tgl Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.41 2002/04/11 19:59:54 tgl Exp $
-->
<chapter id="catalogs">
@@ -183,7 +183,11 @@
that matches a query condition) and returns a single value computed
from all these values. Typical aggregate functions are
<function>sum</function>, <function>count</function>, and
- <function>max</function>.
+ <function>max</function>. Each entry in
+ <structname>pg_aggregate</structname> is an extension of an entry
+ in <structname>pg_proc</structname>. The <structname>pg_proc</structname>
+ entry carries the aggregate's name, input and output datatypes, and
+ other information that is similar to ordinary functions.
</para>
<table>
@@ -200,48 +204,30 @@
</thead>
<tbody>
<row>
- <entry>aggname</entry>
- <entry><type>name</type></entry>
- <entry></entry>
- <entry>Name of the aggregate function</entry>
- </row>
- <row>
- <entry>aggowner</entry>
- <entry><type>int4</type></entry>
- <entry>pg_shadow.usesysid</entry>
- <entry>Owner (creator) of the aggregate function</entry>
+ <entry>aggfnoid</entry>
+ <entry><type>regproc</type></entry>
+ <entry>pg_proc.oid</entry>
+ <entry>pg_proc OID of the aggregate function</entry>
</row>
<row>
<entry>aggtransfn</entry>
- <entry><type>regproc</type> (function)</entry>
+ <entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry>Transition function</entry>
</row>
<row>
<entry>aggfinalfn</entry>
- <entry><type>regproc</type> (function)</entry>
+ <entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry>Final function</entry>
</row>
<row>
- <entry>aggbasetype</entry>
- <entry><type>oid</type></entry>
- <entry>pg_type.oid</entry>
- <entry>The input data type for this aggregate function</entry>
- </row>
- <row>
<entry>aggtranstype</entry>
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
<entry>The type of the aggregate function's internal transition (state) data</entry>
</row>
<row>
- <entry>aggfinaltype</entry>
- <entry><type>oid</type></entry>
- <entry>pg_type.oid</entry>
- <entry>The type of the result</entry>
- </row>
- <row>
<entry>agginitval</entry>
<entry><type>text</type></entry>
<entry></entry>
@@ -263,12 +249,6 @@
functions and the meaning of the transition functions, etc.
</para>
- <para>
- An aggregate function is identified through name
- <emphasis>and</emphasis> argument type. Hence aggname and aggbasetype
- are the composite primary key.
- </para>
-
</sect1>
@@ -1632,6 +1612,12 @@
about the meaning of some fields.
</para>
+ <para>
+ The table contains data for aggregate functions as well as plain functions.
+ If <structfield>proisagg</structfield> is true, there should be a matching
+ row in <structname>pg_aggregate</structname>.
+ </para>
+
<table>
<title>pg_proc Columns</title>
@@ -1677,10 +1663,10 @@
</row>
<row>
- <entry>proisinh</entry>
+ <entry>proisagg</entry>
<entry><type>bool</type></entry>
<entry></entry>
- <entry>unused</entry>
+ <entry>Function is an aggregate function</entry>
</row>
<row>
@@ -1691,6 +1677,13 @@
</row>
<row>
+ <entry>proimplicit</entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Function may be invoked as an implicit type coercion</entry>
+ </row>
+
+ <row>
<entry>proisstrict</entry>
<entry><type>bool</type></entry>
<entry></entry>
@@ -1703,6 +1696,14 @@
</row>
<row>
+ <entry>proretset</entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Function returns a set (ie, multiple values of the specified
+ data type)</entry>
+ </row>
+
+ <row>
<entry>provolatile</entry>
<entry><type>char</type></entry>
<entry></entry>
@@ -1729,14 +1730,6 @@
</row>
<row>
- <entry>proretset</entry>
- <entry><type>bool</type></entry>
- <entry></entry>
- <entry>Function returns a set (ie, multiple values of the specified
- data type)</entry>
- </row>
-
- <row>
<entry>prorettype</entry>
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml
index 8c5e3f7f481..6a421c2a5fd 100644
--- a/doc/src/sgml/ref/create_aggregate.sgml
+++ b/doc/src/sgml/ref/create_aggregate.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_aggregate.sgml,v 1.16 2001/12/08 03:24:34 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_aggregate.sgml,v 1.17 2002/04/11 19:59:55 tgl Exp $
PostgreSQL documentation
-->
@@ -168,8 +168,9 @@ CREATE
<para>
An aggregate function is identified by its name and input data type.
Two aggregates can have the same name if they operate on different
- input types. To avoid confusion, do not make an ordinary function
- of the same name and input data type as an aggregate.
+ input types. The
+ name and input data type of an aggregate must also be distinct from
+ the name and input data type of every ordinary function.
</para>
<para>
An aggregate function is made from one or two ordinary
diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml
index 28c54e1eb89..9c47721dc54 100644
--- a/doc/src/sgml/ref/create_function.sgml
+++ b/doc/src/sgml/ref/create_function.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.35 2002/04/05 00:31:24 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.36 2002/04/11 19:59:55 tgl Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
@@ -214,6 +214,18 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>implicitCoercion</term>
+ <listitem>
+ <para>
+ <option>implicitCoercion</option> indicates that the function
+ may be used for implicit type conversions.
+ See <xref linkend="coercion-functions"
+ endterm="coercion-functions-title"> for more detail.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
Attribute names are not case-sensitive.
@@ -311,6 +323,54 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para>
</refsect1>
+ <refsect1 id="COERCION-FUNCTIONS">
+ <refsect1info>
+ <date>2002-04-11</date>
+ </refsect1info>
+ <title id="coercion-functions-title">
+ Type Coercion Functions
+ </title>
+ <para>
+ A function that has one parameter and is named the same as its output
+ datatype is considered to be a <firstterm>type coercion function</>:
+ it can be invoked to convert a value of its input datatype into a value
+ of its output datatype. For example,
+<programlisting>
+ SELECT CAST(42 AS text);
+</programlisting>
+ converts the integer constant 42 to text by invoking a function
+ <literal>text(int4)</>, if such a function exists and returns type
+ text. (If no suitable conversion function can be found, the cast fails.)
+ </para>
+
+ <para>
+ If a potential coercion function is marked <literal>implicitCoercion</>,
+ then it can be invoked in any context where the conversion it defines
+ is required. Coercion functions not so marked can be invoked only by
+ explicit <literal>CAST</>,
+ <replaceable>x</><literal>::</><replaceable>typename</>,
+ or <replaceable>typename</>(<replaceable>x</>) constructs.
+ For example, supposing that foo.f1 is a column of type text, then
+<programlisting>
+ INSERT INTO foo(f1) VALUES(42);
+</programlisting>
+ will be allowed if <literal>text(int4)</> is marked
+ <literal>implicitCoercion</>, otherwise not.
+ </para>
+
+ <para>
+ It is wise to be conservative about marking coercion functions as
+ implicit coercions. An overabundance of implicit coercion paths
+ can cause <productname>PostgreSQL</productname> to choose surprising
+ interpretations of commands,
+ or to be unable to resolve commands at all because there are multiple
+ possible interpretations. A good rule of thumb is to make coercions
+ implicitly invokable only for information-preserving transformations
+ between types in the same general type category. For example, int2
+ to int4 coercion can reasonably be implicit, but be wary of marking
+ int4 to text or float8 to int4 as implicit coercions.
+ </para>
+ </refsect1>
<refsect1 id="sql-createfunction-examples">
<title>Examples</title>
@@ -356,8 +416,8 @@ CREATE TABLE product (
</para>
<para>
- This example creates a function that does type conversion between the
- user-defined type complex, and the internal type point. The
+ This example creates a function that does type conversion from the
+ user-defined type complex to the built-in type point. The
function is implemented by a dynamically loaded object that was
compiled from C source (we illustrate the now-deprecated alternative
of specifying the absolute file name to the shared object file).