Skip to content

Commit 902a6a0

Browse files
committed
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.
1 parent 3f6299d commit 902a6a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2528
-2438
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--
22
Documentation of the system catalogs, directed toward PostgreSQL developers
3-
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.40 2002/04/05 00:31:22 tgl Exp $
3+
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.41 2002/04/11 19:59:54 tgl Exp $
44
-->
55

66
<chapter id="catalogs">
@@ -183,7 +183,11 @@
183183
that matches a query condition) and returns a single value computed
184184
from all these values. Typical aggregate functions are
185185
<function>sum</function>, <function>count</function>, and
186-
<function>max</function>.
186+
<function>max</function>. Each entry in
187+
<structname>pg_aggregate</structname> is an extension of an entry
188+
in <structname>pg_proc</structname>. The <structname>pg_proc</structname>
189+
entry carries the aggregate's name, input and output datatypes, and
190+
other information that is similar to ordinary functions.
187191
</para>
188192

189193
<table>
@@ -200,47 +204,29 @@
200204
</thead>
201205
<tbody>
202206
<row>
203-
<entry>aggname</entry>
204-
<entry><type>name</type></entry>
205-
<entry></entry>
206-
<entry>Name of the aggregate function</entry>
207-
</row>
208-
<row>
209-
<entry>aggowner</entry>
210-
<entry><type>int4</type></entry>
211-
<entry>pg_shadow.usesysid</entry>
212-
<entry>Owner (creator) of the aggregate function</entry>
207+
<entry>aggfnoid</entry>
208+
<entry><type>regproc</type></entry>
209+
<entry>pg_proc.oid</entry>
210+
<entry>pg_proc OID of the aggregate function</entry>
213211
</row>
214212
<row>
215213
<entry>aggtransfn</entry>
216-
<entry><type>regproc</type> (function)</entry>
214+
<entry><type>regproc</type></entry>
217215
<entry>pg_proc.oid</entry>
218216
<entry>Transition function</entry>
219217
</row>
220218
<row>
221219
<entry>aggfinalfn</entry>
222-
<entry><type>regproc</type> (function)</entry>
220+
<entry><type>regproc</type></entry>
223221
<entry>pg_proc.oid</entry>
224222
<entry>Final function</entry>
225223
</row>
226-
<row>
227-
<entry>aggbasetype</entry>
228-
<entry><type>oid</type></entry>
229-
<entry>pg_type.oid</entry>
230-
<entry>The input data type for this aggregate function</entry>
231-
</row>
232224
<row>
233225
<entry>aggtranstype</entry>
234226
<entry><type>oid</type></entry>
235227
<entry>pg_type.oid</entry>
236228
<entry>The type of the aggregate function's internal transition (state) data</entry>
237229
</row>
238-
<row>
239-
<entry>aggfinaltype</entry>
240-
<entry><type>oid</type></entry>
241-
<entry>pg_type.oid</entry>
242-
<entry>The type of the result</entry>
243-
</row>
244230
<row>
245231
<entry>agginitval</entry>
246232
<entry><type>text</type></entry>
@@ -263,12 +249,6 @@
263249
functions and the meaning of the transition functions, etc.
264250
</para>
265251

266-
<para>
267-
An aggregate function is identified through name
268-
<emphasis>and</emphasis> argument type. Hence aggname and aggbasetype
269-
are the composite primary key.
270-
</para>
271-
272252
</sect1>
273253

274254

@@ -1632,6 +1612,12 @@
16321612
about the meaning of some fields.
16331613
</para>
16341614

1615+
<para>
1616+
The table contains data for aggregate functions as well as plain functions.
1617+
If <structfield>proisagg</structfield> is true, there should be a matching
1618+
row in <structname>pg_aggregate</structname>.
1619+
</para>
1620+
16351621
<table>
16361622
<title>pg_proc Columns</title>
16371623

@@ -1677,10 +1663,10 @@
16771663
</row>
16781664

16791665
<row>
1680-
<entry>proisinh</entry>
1666+
<entry>proisagg</entry>
16811667
<entry><type>bool</type></entry>
16821668
<entry></entry>
1683-
<entry>unused</entry>
1669+
<entry>Function is an aggregate function</entry>
16841670
</row>
16851671

16861672
<row>
@@ -1690,6 +1676,13 @@
16901676
<entry>not functional</entry>
16911677
</row>
16921678

1679+
<row>
1680+
<entry>proimplicit</entry>
1681+
<entry><type>bool</type></entry>
1682+
<entry></entry>
1683+
<entry>Function may be invoked as an implicit type coercion</entry>
1684+
</row>
1685+
16931686
<row>
16941687
<entry>proisstrict</entry>
16951688
<entry><type>bool</type></entry>
@@ -1702,6 +1695,14 @@
17021695
</entry>
17031696
</row>
17041697

1698+
<row>
1699+
<entry>proretset</entry>
1700+
<entry><type>bool</type></entry>
1701+
<entry></entry>
1702+
<entry>Function returns a set (ie, multiple values of the specified
1703+
data type)</entry>
1704+
</row>
1705+
17051706
<row>
17061707
<entry>provolatile</entry>
17071708
<entry><type>char</type></entry>
@@ -1728,14 +1729,6 @@
17281729
<entry>Number of arguments</entry>
17291730
</row>
17301731

1731-
<row>
1732-
<entry>proretset</entry>
1733-
<entry><type>bool</type></entry>
1734-
<entry></entry>
1735-
<entry>Function returns a set (ie, multiple values of the specified
1736-
data type)</entry>
1737-
</row>
1738-
17391732
<row>
17401733
<entry>prorettype</entry>
17411734
<entry><type>oid</type></entry>

doc/src/sgml/ref/create_aggregate.sgml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_aggregate.sgml,v 1.16 2001/12/08 03:24:34 thomas Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_aggregate.sgml,v 1.17 2002/04/11 19:59:55 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -168,8 +168,9 @@ CREATE
168168
<para>
169169
An aggregate function is identified by its name and input data type.
170170
Two aggregates can have the same name if they operate on different
171-
input types. To avoid confusion, do not make an ordinary function
172-
of the same name and input data type as an aggregate.
171+
input types. The
172+
name and input data type of an aggregate must also be distinct from
173+
the name and input data type of every ordinary function.
173174
</para>
174175
<para>
175176
An aggregate function is made from one or two ordinary

doc/src/sgml/ref/create_function.sgml

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.35 2002/04/05 00:31:24 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.36 2002/04/11 19:59:55 tgl Exp $
33
-->
44

55
<refentry id="SQL-CREATEFUNCTION">
@@ -214,6 +214,18 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
214214
</para>
215215
</listitem>
216216
</varlistentry>
217+
218+
<varlistentry>
219+
<term>implicitCoercion</term>
220+
<listitem>
221+
<para>
222+
<option>implicitCoercion</option> indicates that the function
223+
may be used for implicit type conversions.
224+
See <xref linkend="coercion-functions"
225+
endterm="coercion-functions-title"> for more detail.
226+
</para>
227+
</listitem>
228+
</varlistentry>
217229
</variablelist>
218230

219231
Attribute names are not case-sensitive.
@@ -311,6 +323,54 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
311323
</para>
312324
</refsect1>
313325

326+
<refsect1 id="COERCION-FUNCTIONS">
327+
<refsect1info>
328+
<date>2002-04-11</date>
329+
</refsect1info>
330+
<title id="coercion-functions-title">
331+
Type Coercion Functions
332+
</title>
333+
<para>
334+
A function that has one parameter and is named the same as its output
335+
datatype is considered to be a <firstterm>type coercion function</>:
336+
it can be invoked to convert a value of its input datatype into a value
337+
of its output datatype. For example,
338+
<programlisting>
339+
SELECT CAST(42 AS text);
340+
</programlisting>
341+
converts the integer constant 42 to text by invoking a function
342+
<literal>text(int4)</>, if such a function exists and returns type
343+
text. (If no suitable conversion function can be found, the cast fails.)
344+
</para>
345+
346+
<para>
347+
If a potential coercion function is marked <literal>implicitCoercion</>,
348+
then it can be invoked in any context where the conversion it defines
349+
is required. Coercion functions not so marked can be invoked only by
350+
explicit <literal>CAST</>,
351+
<replaceable>x</><literal>::</><replaceable>typename</>,
352+
or <replaceable>typename</>(<replaceable>x</>) constructs.
353+
For example, supposing that foo.f1 is a column of type text, then
354+
<programlisting>
355+
INSERT INTO foo(f1) VALUES(42);
356+
</programlisting>
357+
will be allowed if <literal>text(int4)</> is marked
358+
<literal>implicitCoercion</>, otherwise not.
359+
</para>
360+
361+
<para>
362+
It is wise to be conservative about marking coercion functions as
363+
implicit coercions. An overabundance of implicit coercion paths
364+
can cause <productname>PostgreSQL</productname> to choose surprising
365+
interpretations of commands,
366+
or to be unable to resolve commands at all because there are multiple
367+
possible interpretations. A good rule of thumb is to make coercions
368+
implicitly invokable only for information-preserving transformations
369+
between types in the same general type category. For example, int2
370+
to int4 coercion can reasonably be implicit, but be wary of marking
371+
int4 to text or float8 to int4 as implicit coercions.
372+
</para>
373+
</refsect1>
314374

315375
<refsect1 id="sql-createfunction-examples">
316376
<title>Examples</title>
@@ -356,8 +416,8 @@ CREATE TABLE product (
356416
</para>
357417

358418
<para>
359-
This example creates a function that does type conversion between the
360-
user-defined type complex, and the internal type point. The
419+
This example creates a function that does type conversion from the
420+
user-defined type complex to the built-in type point. The
361421
function is implemented by a dynamically loaded object that was
362422
compiled from C source (we illustrate the now-deprecated alternative
363423
of specifying the absolute file name to the shared object file).

src/backend/catalog/aclchk.c

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.63 2002/04/11 05:32:02 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.64 2002/04/11 19:59:56 tgl Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -733,7 +733,7 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
733733
Acl *acl;
734734

735735
/*
736-
* Validate userid, find out if he is superuser
736+
* Validate userid, find out if he is superuser, also get usecatupd
737737
*/
738738
tuple = SearchSysCache(SHADOWSYSID,
739739
ObjectIdGetDatum(userid),
@@ -1035,29 +1035,3 @@ pg_proc_ownercheck(Oid proc_oid, Oid userid)
10351035

10361036
return userid == owner_id;
10371037
}
1038-
1039-
/*
1040-
* Ownership check for an aggregate function (specified by OID).
1041-
*/
1042-
bool
1043-
pg_aggr_ownercheck(Oid aggr_oid, Oid userid)
1044-
{
1045-
HeapTuple tuple;
1046-
AclId owner_id;
1047-
1048-
/* Superusers bypass all permission checking. */
1049-
if (superuser_arg(userid))
1050-
return true;
1051-
1052-
tuple = SearchSysCache(AGGOID,
1053-
ObjectIdGetDatum(aggr_oid),
1054-
0, 0, 0);
1055-
if (!HeapTupleIsValid(tuple))
1056-
elog(ERROR, "pg_aggr_ownercheck: aggregate %u not found", aggr_oid);
1057-
1058-
owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner;
1059-
1060-
ReleaseSysCache(tuple);
1061-
1062-
return userid == owner_id;
1063-
}

src/backend/catalog/heap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.194 2002/03/31 06:26:29 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.195 2002/04/11 19:59:56 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1791,7 +1791,7 @@ cookDefault(ParseState *pstate,
17911791
if (type_id != atttypid)
17921792
{
17931793
if (CoerceTargetExpr(pstate, expr, type_id,
1794-
atttypid, atttypmod) == NULL)
1794+
atttypid, atttypmod, false) == NULL)
17951795
elog(ERROR, "Column \"%s\" is of type %s"
17961796
" but default expression is of type %s"
17971797
"\n\tYou will need to rewrite or cast the expression",

src/backend/catalog/indexing.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.87 2002/04/05 00:31:24 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.88 2002/04/11 19:59:57 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -32,7 +32,7 @@
3232
*/
3333

3434
char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
35-
{AggregateNameTypeIndex, AggregateOidIndex};
35+
{AggregateFnoidIndex};
3636
char *Name_pg_am_indices[Num_pg_am_indices] =
3737
{AmNameIndex, AmOidIndex};
3838
char *Name_pg_amop_indices[Num_pg_amop_indices] =

0 commit comments

Comments
 (0)