Pre-v11 appearances of the word "procedure" in v11 docs
I noticed that the word "procedure" appears in at least a few places
in the v11 docs as a not-quite-apt synonym of "function". For example,
https://www.postgresql.org/docs/11/static/plpgsql-trigger.html talks
about "PL/pgSQL Trigger Procedures" which are actually all functions
in practice.
I think that this has the potential to confuse users, since, of
course, a function is a distinct variety of object to a procedure in
v11. Tightening up the wording seems like a good idea. I'm not sure if
this was discussed already, but didn't find anything during a quick
search.
--
Peter Geoghegan
Peter Geoghegan <pg@bowt.ie> writes:
I noticed that the word "procedure" appears in at least a few places
in the v11 docs as a not-quite-apt synonym of "function". For example,
https://www.postgresql.org/docs/11/static/plpgsql-trigger.html talks
about "PL/pgSQL Trigger Procedures" which are actually all functions
in practice.
Agreed, we'd better stop being cavalier about whether that's an
exact synonym or not.
regards, tom lane
On Tue, Aug 14, 2018 at 10:18 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Agreed, we'd better stop being cavalier about whether that's an
exact synonym or not.
I made an open item for this.
--
Peter Geoghegan
What should we do with the use of the keyword PROCEDURE in the CREATE
OPERATOR and CREATE TRIGGER syntaxes?
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
What should we do with the use of the keyword PROCEDURE in the CREATE
OPERATOR and CREATE TRIGGER syntaxes?
We're kinda stuck with that. We could add FUNCTION as a preferred
synonym, perhaps, but I doubt that'd really be worth the trouble.
regards, tom lane
On Tue, Aug 14, 2018 at 1:39 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
We're kinda stuck with that. We could add FUNCTION as a preferred
synonym, perhaps, but I doubt that'd really be worth the trouble.
Seems sufficient to note in the relevant docs that it's a legacy thing.
--
Peter Geoghegan
On 14/08/18 22:39, Tom Lane wrote:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
What should we do with the use of the keyword PROCEDURE in the CREATE
OPERATOR and CREATE TRIGGER syntaxes?We're kinda stuck with that. We could add FUNCTION as a preferred
synonym, perhaps, but I doubt that'd really be worth the trouble.
If someone were to waste their time doing it, would we want FUNCTION or
ROUTINE?
--
Vik Fearing +33 6 46 75 15 36
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
Attached are my proposed patches. The first is the documentation
change, which basically just substitutes the words, with some occasional
rephrasing. And then patches to extend the syntaxes of CREATE OPERATOR,
CREATE TRIGGER, and CREATE EVENT TRIGGER to accept FUNCTION in place of
PROCEDURE. I decided to do that because with the adjustments from the
first patch, the documentation had become comically inconsistent in some
places and it was easier to just fix the underlying problem than to
explain the reasons for the inconsistencies everywhere. I didn't go
around change all the commands in contrib modules etc. to keep the patch
size under control. This could perhaps be done later.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
0001-doc-Update-uses-of-the-word-procedure.patchtext/plain; charset=UTF-8; name=0001-doc-Update-uses-of-the-word-procedure.patch; x-mac-creator=0; x-mac-type=0Download
From 142d34b7532fdd8e439bdf21b00983c13f4325a5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 15 Aug 2018 17:01:39 +0200
Subject: [PATCH 1/3] doc: Update uses of the word "procedure"
Historically, the term procedure was used as a synonym for function in
Postgres/PostgreSQL. Now we have procedures as separate objects from
functions, so we need to clean up the documentation to not mix those
terms.
In particular, mentions of "trigger procedures" are changed to "trigger
functions", and access method "support procedures" are changed to
"support functions". (The latter already used FUNCTION in the SQL
syntax anyway.) Also, the terminology in the SPI chapter has been
cleaned up.
A few tests, examples, and code comments are also adjusted to be
consistent with documentation changes, but not everything.
---
doc/src/sgml/brin.sgml | 52 ++++++------
doc/src/sgml/catalogs.sgml | 20 ++---
doc/src/sgml/event-trigger.sgml | 6 +-
doc/src/sgml/func.sgml | 2 +-
doc/src/sgml/plhandler.sgml | 2 +-
doc/src/sgml/plperl.sgml | 2 +-
doc/src/sgml/plpgsql.sgml | 34 ++++----
doc/src/sgml/pltcl.sgml | 40 ++++-----
doc/src/sgml/ref/alter_opfamily.sgml | 4 +-
doc/src/sgml/ref/create_language.sgml | 2 +-
doc/src/sgml/ref/create_opclass.sgml | 6 +-
doc/src/sgml/ref/create_operator.sgml | 8 +-
doc/src/sgml/ref/create_trigger.sgml | 2 +-
doc/src/sgml/spi.sgml | 83 +++++++++----------
doc/src/sgml/xindex.sgml | 2 +-
doc/src/sgml/xplang.sgml | 4 +-
src/backend/access/gin/ginvalidate.c | 2 +-
src/backend/access/gist/gistvalidate.c | 2 +-
src/backend/access/hash/hashutil.c | 4 +-
src/backend/access/hash/hashvalidate.c | 4 +-
src/backend/access/spgist/spgvalidate.c | 2 +-
src/backend/commands/opclasscmds.c | 30 +++----
src/bin/psql/describe.c | 2 +-
src/include/access/hash.h | 12 +--
src/test/regress/expected/alter_generic.out | 16 ++--
src/test/regress/expected/create_operator.out | 6 +-
src/test/regress/sql/create_operator.sql | 6 +-
27 files changed, 174 insertions(+), 181 deletions(-)
diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml
index f02e061bc1..f47e1968a4 100644
--- a/doc/src/sgml/brin.sgml
+++ b/doc/src/sgml/brin.sgml
@@ -537,7 +537,7 @@ <title>Extensibility</title>
} BrinOpcInfo;
</programlisting>
<structname>BrinOpcInfo</structname>.<structfield>oi_opaque</structfield> can be used by the
- operator class routines to pass information between support procedures
+ operator class routines to pass information between support functions
during an index scan.
</para>
</listitem>
@@ -587,27 +587,27 @@ <title>Extensibility</title>
defined by the user for other data types using equivalent definitions,
without having to write any source code; appropriate catalog entries being
declared is enough. Note that assumptions about the semantics of operator
- strategies are embedded in the support procedures' source code.
+ strategies are embedded in the support functions' source code.
</para>
<para>
Operator classes that implement completely different semantics are also
- possible, provided implementations of the four main support procedures
+ possible, provided implementations of the four main support functions
described above are written. Note that backwards compatibility across major
- releases is not guaranteed: for example, additional support procedures might
+ releases is not guaranteed: for example, additional support functions might
be required in later releases.
</para>
<para>
To write an operator class for a data type that implements a totally
- ordered set, it is possible to use the minmax support procedures
+ ordered set, it is possible to use the minmax support functions
alongside the corresponding operators, as shown in
<xref linkend="brin-extensibility-minmax-table"/>.
- All operator class members (procedures and operators) are mandatory.
+ All operator class members (functions and operators) are mandatory.
</para>
<table id="brin-extensibility-minmax-table">
- <title>Procedure and Support Numbers for Minmax Operator Classes</title>
+ <title>Function and Support Numbers for Minmax Operator Classes</title>
<tgroup cols="2">
<thead>
<row>
@@ -617,19 +617,19 @@ <title>Procedure and Support Numbers for Minmax Operator Classes</title>
</thead>
<tbody>
<row>
- <entry>Support Procedure 1</entry>
+ <entry>Support Function 1</entry>
<entry>internal function <function>brin_minmax_opcinfo()</function></entry>
</row>
<row>
- <entry>Support Procedure 2</entry>
+ <entry>Support Function 2</entry>
<entry>internal function <function>brin_minmax_add_value()</function></entry>
</row>
<row>
- <entry>Support Procedure 3</entry>
+ <entry>Support Function 3</entry>
<entry>internal function <function>brin_minmax_consistent()</function></entry>
</row>
<row>
- <entry>Support Procedure 4</entry>
+ <entry>Support Function 4</entry>
<entry>internal function <function>brin_minmax_union()</function></entry>
</row>
<row>
@@ -659,7 +659,7 @@ <title>Procedure and Support Numbers for Minmax Operator Classes</title>
<para>
To write an operator class for a complex data type which has values
included within another type, it's possible to use the inclusion support
- procedures alongside the corresponding operators, as shown
+ functions alongside the corresponding operators, as shown
in <xref linkend="brin-extensibility-inclusion-table"/>. It requires
only a single additional function, which can be written in any language.
More functions can be defined for additional functionality. All operators
@@ -668,7 +668,7 @@ <title>Procedure and Support Numbers for Minmax Operator Classes</title>
</para>
<table id="brin-extensibility-inclusion-table">
- <title>Procedure and Support Numbers for Inclusion Operator Classes</title>
+ <title>Function and Support Numbers for Inclusion Operator Classes</title>
<tgroup cols="3">
<thead>
<row>
@@ -679,42 +679,42 @@ <title>Procedure and Support Numbers for Inclusion Operator Classes</title>
</thead>
<tbody>
<row>
- <entry>Support Procedure 1</entry>
+ <entry>Support Function 1</entry>
<entry>internal function <function>brin_inclusion_opcinfo()</function></entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 2</entry>
+ <entry>Support Function 2</entry>
<entry>internal function <function>brin_inclusion_add_value()</function></entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 3</entry>
+ <entry>Support Function 3</entry>
<entry>internal function <function>brin_inclusion_consistent()</function></entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 4</entry>
+ <entry>Support Function 4</entry>
<entry>internal function <function>brin_inclusion_union()</function></entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 11</entry>
+ <entry>Support Function 11</entry>
<entry>function to merge two elements</entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 12</entry>
+ <entry>Support Function 12</entry>
<entry>optional function to check whether two elements are mergeable</entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 13</entry>
+ <entry>Support Function 13</entry>
<entry>optional function to check if an element is contained within another</entry>
<entry></entry>
</row>
<row>
- <entry>Support Procedure 14</entry>
+ <entry>Support Function 14</entry>
<entry>optional function to check whether an element is empty</entry>
<entry></entry>
</row>
@@ -803,7 +803,7 @@ <title>Procedure and Support Numbers for Inclusion Operator Classes</title>
</table>
<para>
- Support procedure numbers 1-10 are reserved for the BRIN internal
+ Support function numbers 1-10 are reserved for the BRIN internal
functions, so the SQL level functions start with number 11. Support
function number 11 is the main function required to build the index.
It should accept two arguments with the same data type as the operator class,
@@ -814,11 +814,11 @@ <title>Procedure and Support Numbers for Inclusion Operator Classes</title>
</para>
<para>
- Support procedure numbers 12 and 14 are provided to support
- irregularities of built-in data types. Procedure number 12
+ Support function numbers 12 and 14 are provided to support
+ irregularities of built-in data types. Function number 12
is used to support network addresses from different families which
- are not mergeable. Procedure number 14 is used to support
- empty ranges. Procedure number 13 is an optional but
+ are not mergeable. Function number 14 is used to support
+ empty ranges. Function number 13 is an optional but
recommended one, which allows the new value to be checked before
it is passed to the union function. As the BRIN framework can shortcut
some operations when the union is not changed, using this
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 3bb48d4ccf..07e8b3325f 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -67,7 +67,7 @@ <title>System Catalogs</title>
<row>
<entry><link linkend="catalog-pg-amproc"><structname>pg_amproc</structname></link></entry>
- <entry>access method support procedures</entry>
+ <entry>access method support functions</entry>
</row>
<row>
@@ -814,8 +814,8 @@ <title><structname>pg_amproc</structname></title>
<para>
The catalog <structname>pg_amproc</structname> stores information about
- support procedures associated with access method operator families. There
- is one row for each support procedure belonging to an operator family.
+ support functions associated with access method operator families. There
+ is one row for each support function belonging to an operator family.
</para>
<table>
@@ -864,14 +864,14 @@ <title><structname>pg_amproc</structname> Columns</title>
<entry><structfield>amprocnum</structfield></entry>
<entry><type>int2</type></entry>
<entry></entry>
- <entry>Support procedure number</entry>
+ <entry>Support function number</entry>
</row>
<row>
<entry><structfield>amproc</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
- <entry>OID of the procedure</entry>
+ <entry>OID of the function</entry>
</row>
</tbody>
@@ -882,9 +882,9 @@ <title><structname>pg_amproc</structname> Columns</title>
The usual interpretation of the
<structfield>amproclefttype</structfield> and <structfield>amprocrighttype</structfield> fields
is that they identify the left and right input types of the operator(s)
- that a particular support procedure supports. For some access methods
- these match the input data type(s) of the support procedure itself, for
- others not. There is a notion of <quote>default</quote> support procedures for
+ that a particular support function supports. For some access methods
+ these match the input data type(s) of the support function itself, for
+ others not. There is a notion of <quote>default</quote> support functions for
an index, which are those with <structfield>amproclefttype</structfield> and
<structfield>amprocrighttype</structfield> both equal to the index operator class's
<structfield>opcintype</structfield>.
@@ -2471,7 +2471,7 @@ <title><structname>pg_conversion</structname></title>
<para>
The catalog <structname>pg_conversion</structname> describes
- encoding conversion procedures. See <xref linkend="sql-createconversion"/>
+ encoding conversion functions. See <xref linkend="sql-createconversion"/>
for more information.
</para>
@@ -2537,7 +2537,7 @@ <title><structname>pg_conversion</structname> Columns</title>
<entry><structfield>conproc</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
- <entry>Conversion procedure</entry>
+ <entry>Conversion function</entry>
</row>
<row>
diff --git a/doc/src/sgml/event-trigger.sgml b/doc/src/sgml/event-trigger.sgml
index 0a8860490a..be975d1399 100644
--- a/doc/src/sgml/event-trigger.sgml
+++ b/doc/src/sgml/event-trigger.sgml
@@ -1053,9 +1053,9 @@ <title>A Complete Event Trigger Example</title>
<screen>
=# \dy
List of event triggers
- Name | Event | Owner | Enabled | Procedure | Tags
--------+-------------------+-------+---------+-----------+------
- noddl | ddl_command_start | dim | enabled | noddl |
+ Name | Event | Owner | Enabled | Function | Tags
+-------+-------------------+-------+---------+----------+------
+ noddl | ddl_command_start | dim | enabled | noddl |
(1 row)
=# CREATE TABLE foo(id serial);
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index edc9be92a6..c6f61ce2c0 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -12360,7 +12360,7 @@ <title>Conditional Expressions</title>
<tip>
<para>
If your needs go beyond the capabilities of these conditional
- expressions, you might want to consider writing a stored procedure
+ expressions, you might want to consider writing a server-side function
in a more expressive programming language.
</para>
</tip>
diff --git a/doc/src/sgml/plhandler.sgml b/doc/src/sgml/plhandler.sgml
index 4f8c4d040a..73cd7d1387 100644
--- a/doc/src/sgml/plhandler.sgml
+++ b/doc/src/sgml/plhandler.sgml
@@ -119,7 +119,7 @@ <title>Writing A Procedural Language Handler</title>
if (CALLED_AS_TRIGGER(fcinfo))
{
/*
- * Called as a trigger procedure
+ * Called as a trigger function
*/
TriggerData *trigdata = (TriggerData *) fcinfo->context;
diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml
index 82f56cb8ab..6296a226b6 100644
--- a/doc/src/sgml/plperl.sgml
+++ b/doc/src/sgml/plperl.sgml
@@ -1337,7 +1337,7 @@ <title>PL/Perl Event Triggers</title>
</para>
<para>
- The return value of the trigger procedure is ignored.
+ The return value of the trigger function is ignored.
</para>
<para>
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index d6688e13f4..abe67fa50e 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -19,7 +19,7 @@ <title>Overview</title>
<itemizedlist>
<listitem>
<para>
- can be used to create functions and trigger procedures,
+ can be used to create functions and triggers,
</para>
</listitem>
<listitem>
@@ -305,7 +305,7 @@ <title>Structure of <application>PL/pgSQL</application></title>
for transaction
control. <application>PL/pgSQL</application>'s <command>BEGIN</command>/<command>END</command>
are only for grouping; they do not start or end a transaction.
- Functions and trigger procedures are always executed within a transaction
+ Functions are always executed within a transaction
established by an outer query — they cannot start or commit that
transaction, since there would be no context for them to execute in.
However, a block containing an <literal>EXCEPTION</literal> clause effectively
@@ -579,7 +579,7 @@ <title><literal>ALIAS</literal></title>
function parameters. The main practical use for this is to assign
a different name for variables with predetermined names, such as
<varname>NEW</varname> or <varname>OLD</varname> within
- a trigger procedure.
+ a trigger function.
</para>
<para>
@@ -3796,7 +3796,7 @@ <title>Checking Assertions</title>
</sect1>
<sect1 id="plpgsql-trigger">
- <title>Trigger Procedures</title>
+ <title>Trigger Functions</title>
<indexterm zone="plpgsql-trigger">
<primary>trigger</primary>
@@ -3805,8 +3805,8 @@ <title>Trigger Procedures</title>
<para>
<application>PL/pgSQL</application> can be used to define trigger
- procedures on data changes or database events.
- A trigger procedure is created with the <command>CREATE FUNCTION</command>
+ functions on data changes or database events.
+ A trigger function is created with the <command>CREATE FUNCTION</command>
command, declaring it as a function with no arguments and a return type of
<type>trigger</type> (for data change triggers) or
<type>event_trigger</type> (for database event triggers).
@@ -3946,7 +3946,7 @@ <title>Triggers on Data Changes</title>
<listitem>
<para>
Data type <type>integer</type>; the number of arguments given to the trigger
- procedure in the <command>CREATE TRIGGER</command> statement.
+ function in the <command>CREATE TRIGGER</command> statement.
</para>
</listitem>
</varlistentry>
@@ -4025,11 +4025,11 @@ <title>Triggers on Data Changes</title>
<para>
<xref linkend="plpgsql-trigger-example"/> shows an example of a
- trigger procedure in <application>PL/pgSQL</application>.
+ trigger function in <application>PL/pgSQL</application>.
</para>
<example id="plpgsql-trigger-example">
- <title>A <application>PL/pgSQL</application> Trigger Procedure</title>
+ <title>A <application>PL/pgSQL</application> Trigger Function</title>
<para>
This example trigger ensures that any time a row is inserted or updated
@@ -4078,11 +4078,11 @@ <title>A <application>PL/pgSQL</application> Trigger Procedure</title>
holds a row for each insert, update, or delete that occurs. This approach
can be thought of as auditing changes to a table.
<xref linkend="plpgsql-trigger-audit-example"/> shows an example of an
- audit trigger procedure in <application>PL/pgSQL</application>.
+ audit trigger function in <application>PL/pgSQL</application>.
</para>
<example id="plpgsql-trigger-audit-example">
- <title>A <application>PL/pgSQL</application> Trigger Procedure For Auditing</title>
+ <title>A <application>PL/pgSQL</application> Trigger Function For Auditing</title>
<para>
This example trigger ensures that any insert, update or delete of a row
@@ -4139,7 +4139,7 @@ <title>A <application>PL/pgSQL</application> Trigger Procedure For Auditing</tit
</para>
<example id="plpgsql-view-trigger-audit-example">
- <title>A <application>PL/pgSQL</application> View Trigger Procedure For Auditing</title>
+ <title>A <application>PL/pgSQL</application> View Trigger Function For Auditing</title>
<para>
This example uses a trigger on the view to make it updatable, and
@@ -4215,13 +4215,13 @@ <title>A <application>PL/pgSQL</application> View Trigger Procedure For Auditing
This technique is commonly used in Data Warehousing, where the tables
of measured or observed data (called fact tables) might be extremely large.
<xref linkend="plpgsql-trigger-summary-example"/> shows an example of a
- trigger procedure in <application>PL/pgSQL</application> that maintains
+ trigger function in <application>PL/pgSQL</application> that maintains
a summary table for a fact table in a data warehouse.
</para>
<example id="plpgsql-trigger-summary-example">
- <title>A <application>PL/pgSQL</application> Trigger Procedure For Maintaining A Summary Table</title>
+ <title>A <application>PL/pgSQL</application> Trigger Function For Maintaining A Summary Table</title>
<para>
The schema detailed here is partly based on the <emphasis>Grocery Store
@@ -4445,7 +4445,7 @@ <title>Triggers on Events</title>
<para>
<application>PL/pgSQL</application> can be used to define
<link linkend="event-triggers">event triggers</link>.
- <productname>PostgreSQL</productname> requires that a procedure that
+ <productname>PostgreSQL</productname> requires that a function that
is to be called as an event trigger must be declared as a function with
no arguments and a return type of <literal>event_trigger</literal>.
</para>
@@ -4480,11 +4480,11 @@ <title>Triggers on Events</title>
<para>
<xref linkend="plpgsql-event-trigger-example"/> shows an example of an
- event trigger procedure in <application>PL/pgSQL</application>.
+ event trigger function in <application>PL/pgSQL</application>.
</para>
<example id="plpgsql-event-trigger-example">
- <title>A <application>PL/pgSQL</application> Event Trigger Procedure</title>
+ <title>A <application>PL/pgSQL</application> Event Trigger Function</title>
<para>
This example trigger simply raises a <literal>NOTICE</literal> message
diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml
index 01f6207d36..97906a67df 100644
--- a/doc/src/sgml/pltcl.sgml
+++ b/doc/src/sgml/pltcl.sgml
@@ -16,7 +16,7 @@ <title>PL/Tcl - Tcl Procedural Language</title>
<productname>PostgreSQL</productname> database system
that enables the <ulink url="http://www.tcl.tk/">
Tcl language</ulink> to be used to write functions and
- trigger procedures.
+ triggers.
</para>
<!-- **** PL/Tcl overview **** -->
@@ -587,7 +587,7 @@ <title>Database Access from PL/Tcl</title>
</sect1>
<sect1 id="pltcl-trigger">
- <title>Trigger Procedures in PL/Tcl</title>
+ <title>Trigger Functions in PL/Tcl</title>
<indexterm>
<primary>trigger</primary>
@@ -595,13 +595,13 @@ <title>Trigger Procedures in PL/Tcl</title>
</indexterm>
<para>
- Trigger procedures can be written in PL/Tcl.
- <productname>PostgreSQL</productname> requires that a procedure that is to be called
+ Trigger functions can be written in PL/Tcl.
+ <productname>PostgreSQL</productname> requires that a function that is to be called
as a trigger must be declared as a function with no arguments
and a return type of <literal>trigger</literal>.
</para>
<para>
- The information from the trigger manager is passed to the procedure body
+ The information from the trigger manager is passed to the function body
in the following variables:
<variablelist>
@@ -619,7 +619,7 @@ <title>Trigger Procedures in PL/Tcl</title>
<term><varname>$TG_relid</varname></term>
<listitem>
<para>
- The object ID of the table that caused the trigger procedure
+ The object ID of the table that caused the trigger function
to be invoked.
</para>
</listitem>
@@ -629,7 +629,7 @@ <title>Trigger Procedures in PL/Tcl</title>
<term><varname>$TG_table_name</varname></term>
<listitem>
<para>
- The name of the table that caused the trigger procedure
+ The name of the table that caused the trigger function
to be invoked.
</para>
</listitem>
@@ -639,7 +639,7 @@ <title>Trigger Procedures in PL/Tcl</title>
<term><varname>$TG_table_schema</varname></term>
<listitem>
<para>
- The schema of the table that caused the trigger procedure
+ The schema of the table that caused the trigger function
to be invoked.
</para>
</listitem>
@@ -722,9 +722,9 @@ <title>Trigger Procedures in PL/Tcl</title>
<term><varname>$args</varname></term>
<listitem>
<para>
- A Tcl list of the arguments to the procedure as given in the
+ A Tcl list of the arguments to the function as given in the
<command>CREATE TRIGGER</command> statement. These arguments are also accessible as
- <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> in the procedure body.
+ <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> in the function body.
</para>
</listitem>
</varlistentry>
@@ -733,7 +733,7 @@ <title>Trigger Procedures in PL/Tcl</title>
</para>
<para>
- The return value from a trigger procedure can be one of the strings
+ The return value from a trigger function can be one of the strings
<literal>OK</literal> or <literal>SKIP</literal>, or a list of column name/value pairs.
If the return value is <literal>OK</literal>,
the operation (<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>)
@@ -764,7 +764,7 @@ <title>Trigger Procedures in PL/Tcl</title>
</tip>
<para>
- Here's a little example trigger procedure that forces an integer value
+ Here's a little example trigger function that forces an integer value
in a table to keep track of the number of updates that are performed on the
row. For new rows inserted, the value is initialized to 0 and then
incremented on every update operation.
@@ -792,14 +792,14 @@ <title>Trigger Procedures in PL/Tcl</title>
FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
</programlisting>
- Notice that the trigger procedure itself does not know the column
+ Notice that the trigger function itself does not know the column
name; that's supplied from the trigger arguments. This lets the
- trigger procedure be reused with different tables.
+ trigger function be reused with different tables.
</para>
</sect1>
<sect1 id="pltcl-event-trigger">
- <title>Event Trigger Procedures in PL/Tcl</title>
+ <title>Event Trigger Functions in PL/Tcl</title>
<indexterm>
<primary>event trigger</primary>
@@ -807,13 +807,13 @@ <title>Event Trigger Procedures in PL/Tcl</title>
</indexterm>
<para>
- Event trigger procedures can be written in PL/Tcl.
- <productname>PostgreSQL</productname> requires that a procedure that is
+ Event trigger functions can be written in PL/Tcl.
+ <productname>PostgreSQL</productname> requires that a function that is
to be called as an event trigger must be declared as a function with no
arguments and a return type of <literal>event_trigger</literal>.
</para>
<para>
- The information from the trigger manager is passed to the procedure body
+ The information from the trigger manager is passed to the function body
in the following variables:
<variablelist>
@@ -839,11 +839,11 @@ <title>Event Trigger Procedures in PL/Tcl</title>
</para>
<para>
- The return value of the trigger procedure is ignored.
+ The return value of the trigger function is ignored.
</para>
<para>
- Here's a little example event trigger procedure that simply raises
+ Here's a little example event trigger function that simply raises
a <literal>NOTICE</literal> message each time a supported command is
executed:
diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml
index 3c0922c645..848156c9d7 100644
--- a/doc/src/sgml/ref/alter_opfamily.sgml
+++ b/doc/src/sgml/ref/alter_opfamily.sgml
@@ -185,7 +185,7 @@ <title>Parameters</title>
<term><replaceable class="parameter">support_number</replaceable></term>
<listitem>
<para>
- The index method's support procedure number for a
+ The index method's support function number for a
function associated with the operator family.
</para>
</listitem>
@@ -196,7 +196,7 @@ <title>Parameters</title>
<listitem>
<para>
The name (optionally schema-qualified) of a function that is an index
- method support procedure for the operator family. If no argument list
+ method support function for the operator family. If no argument list
is specified, the name must be unique in its schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml
index 6bb69cf0ef..13b28b1ccc 100644
--- a/doc/src/sgml/ref/create_language.sgml
+++ b/doc/src/sgml/ref/create_language.sgml
@@ -33,7 +33,7 @@ <title>Description</title>
<para>
<command>CREATE LANGUAGE</command> registers a new
procedural language with a <productname>PostgreSQL</productname>
- database. Subsequently, functions and trigger procedures can be
+ database. Subsequently, functions and procedures can be
defined in this new language.
</para>
diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml
index 0714aeca7c..dd5252fd97 100644
--- a/doc/src/sgml/ref/create_opclass.sgml
+++ b/doc/src/sgml/ref/create_opclass.sgml
@@ -38,7 +38,7 @@ <title>Description</title>
An operator class defines how a particular data type can be used with
an index. The operator class specifies that certain operators will fill
particular roles or <quote>strategies</quote> for this data type and this
- index method. The operator class also specifies the support procedures to
+ index method. The operator class also specifies the support functions to
be used by
the index method when the operator class is selected for an
index column. All the operators and functions used by an operator
@@ -201,7 +201,7 @@ <title>Parameters</title>
<term><replaceable class="parameter">support_number</replaceable></term>
<listitem>
<para>
- The index method's support procedure number for a
+ The index method's support function number for a
function associated with the operator class.
</para>
</listitem>
@@ -212,7 +212,7 @@ <title>Parameters</title>
<listitem>
<para>
The name (optionally schema-qualified) of a function that is an
- index method support procedure for the operator class.
+ index method support function for the operator class.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
index 35f2f46985..c8263437ab 100644
--- a/doc/src/sgml/ref/create_operator.sgml
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -94,7 +94,7 @@ <title>Description</title>
<para>
The <replaceable class="parameter">function_name</replaceable>
- procedure must have been previously defined using <command>CREATE
+ function must have been previously defined using <command>CREATE
FUNCTION</command> and must be defined to accept the correct number
of arguments (either one or two) of the indicated types.
</para>
@@ -264,11 +264,11 @@ <title>Examples</title>
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
- PROCEDURE = area_equal_procedure,
+ PROCEDURE = area_equal_function,
COMMUTATOR = ===,
NEGATOR = !==,
- RESTRICT = area_restriction_procedure,
- JOIN = area_join_procedure,
+ RESTRICT = area_restriction_function,
+ JOIN = area_join_function,
HASHES, MERGES
);
</programlisting></para>
diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml
index 7b971ee6b4..b2dddafb46 100644
--- a/doc/src/sgml/ref/create_trigger.sgml
+++ b/doc/src/sgml/ref/create_trigger.sgml
@@ -348,7 +348,7 @@ <title>Parameters</title>
<listitem>
<para>
- This specifies whether the trigger procedure should be fired
+ This specifies whether the trigger function should be fired
once for every row affected by the trigger event, or just once
per SQL statement. If neither is specified, <literal>FOR EACH
STATEMENT</literal> is the default. Constraint triggers can only
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml
index 2dad215859..9db11d22fb 100644
--- a/doc/src/sgml/spi.sgml
+++ b/doc/src/sgml/spi.sgml
@@ -21,23 +21,16 @@ <title>Server Programming Interface</title>
<note>
<para>
The available procedural languages provide various means to
- execute SQL commands from procedures. Most of these facilities are
+ execute SQL commands from functions. Most of these facilities are
based on SPI, so this documentation might be of use for users
of those languages as well.
</para>
</note>
- <para>
- To avoid misunderstanding we'll use the term <quote>function</quote>
- when we speak of <acronym>SPI</acronym> interface functions and
- <quote>procedure</quote> for a user-defined C-function that is
- using <acronym>SPI</acronym>.
- </para>
-
<para>
Note that if a command invoked via SPI fails, then control will not be
- returned to your procedure. Rather, the
- transaction or subtransaction in which your procedure executes will be
+ returned to your C function. Rather, the
+ transaction or subtransaction in which your C function executes will be
rolled back. (This might seem surprising given that the SPI functions mostly
have documented error-return conventions. Those conventions only apply
for errors detected within the SPI functions themselves, however.)
@@ -73,7 +66,7 @@ <title>Interface Functions</title>
<refnamediv>
<refname>SPI_connect</refname>
<refname>SPI_connect_ext</refname>
- <refpurpose>connect a procedure to the SPI manager</refpurpose>
+ <refpurpose>connect a C function to the SPI manager</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -91,9 +84,9 @@ <title>Description</title>
<para>
<function>SPI_connect</function> opens a connection from a
- procedure invocation to the SPI manager. You must call this
+ C function invocation to the SPI manager. You must call this
function if you want to execute commands through SPI. Some utility
- SPI functions can be called from unconnected procedures.
+ SPI functions can be called from unconnected C functions.
</para>
<para>
@@ -159,7 +152,7 @@ <title>Return Value</title>
<refnamediv>
<refname>SPI_finish</refname>
- <refpurpose>disconnect a procedure from the SPI manager</refpurpose>
+ <refpurpose>disconnect a C function from the SPI manager</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -174,7 +167,7 @@ <title>Description</title>
<para>
<function>SPI_finish</function> closes an existing connection to
the SPI manager. You must call this function after completing the
- SPI operations needed during your procedure's current invocation.
+ SPI operations needed during your C function's current invocation.
You do not need to worry about making this happen, however, if you
abort the transaction via <literal>elog(ERROR)</literal>. In that
case SPI will clean itself up automatically.
@@ -198,7 +191,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -238,7 +231,7 @@ <title>Description</title>
</para>
<para>
- This function can only be called from a connected procedure.
+ This function can only be called from a connected C function.
</para>
<para>
@@ -345,7 +338,7 @@ <title>Description</title>
<para>
<function>SPI_finish</function> frees all
<structname>SPITupleTable</structname>s allocated during the current
- procedure. You can free a particular result table earlier, if you
+ C function. You can free a particular result table earlier, if you
are done with it, by calling <function>SPI_freetuptable</function>.
</para>
</refsect1>
@@ -539,7 +532,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -555,7 +548,7 @@ <title>Notes</title>
<varname>SPI_processed</varname> and
<varname>SPI_tuptable</varname> (just the pointer, not the contents
of the structure). Save these two global variables into local
- procedure variables if you need to access the result table of
+ C function variables if you need to access the result table of
<function>SPI_execute</function> or another query-execution function
across later calls.
</para>
@@ -835,7 +828,7 @@ <title>Description</title>
<para>
The statement returned by <function>SPI_prepare</function> can be used
- only in the current invocation of the procedure, since
+ only in the current invocation of the C function, since
<function>SPI_finish</function> frees memory allocated for such a
statement. But the statement can be saved for longer using the functions
<function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
@@ -926,7 +919,7 @@ <title>Notes</title>
</para>
<para>
- This function should only be called from a connected procedure.
+ This function should only be called from a connected C function.
</para>
<para>
@@ -1702,9 +1695,9 @@ <title>Description</title>
Using a cursor instead of executing the statement directly has two
benefits. First, the result rows can be retrieved a few at a time,
avoiding memory overrun for queries that return many rows. Second,
- a portal can outlive the current procedure (it can, in fact, live
+ a portal can outlive the current C function (it can, in fact, live
to the end of the current transaction). Returning the portal name
- to the procedure's caller provides a way of returning a row set as
+ to the C function's caller provides a way of returning a row set as
result.
</para>
@@ -2534,7 +2527,7 @@ <title>Description</title>
<function>SPI_prepare</function>) so that it will not be freed
by <function>SPI_finish</function> nor by the transaction manager.
This gives you the ability to reuse prepared statements in the subsequent
- invocations of your procedure in the current session.
+ invocations of your C function in the current session.
</para>
</refsect1>
@@ -2604,7 +2597,7 @@ <title>Description</title>
by <function>SPI_finish</function> nor by the transaction manager,
and returns a pointer to the copied statement. This gives you the
ability to reuse prepared statements in the subsequent invocations of
- your procedure in the current session.
+ your C function in the current session.
</para>
</refsect1>
@@ -2644,7 +2637,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -2757,7 +2750,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -2862,7 +2855,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -2977,7 +2970,7 @@ <title>Return Value</title>
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
<listitem>
<para>
- if called from an unconnected procedure
+ if called from an unconnected C function
</para>
</listitem>
</varlistentry>
@@ -3011,7 +3004,7 @@ <title>Interface Support Functions</title>
<para>
All functions described in this section can be used by both
- connected and unconnected procedures.
+ connected and unconnected C functions.
</para>
<!-- *********************************************** -->
@@ -3655,37 +3648,37 @@ <title>Memory Management</title>
makes it current. <function>SPI_finish</function> restores the
previous current memory context and destroys the context created by
<function>SPI_connect</function>. These actions ensure that
- transient memory allocations made inside your procedure are
- reclaimed at procedure exit, avoiding memory leakage.
+ transient memory allocations made inside your C function are
+ reclaimed at C function exit, avoiding memory leakage.
</para>
<para>
- However, if your procedure needs to return an object in allocated
+ However, if your C function needs to return an object in allocated
memory (such as a value of a pass-by-reference data type), you
cannot allocate that memory using <function>palloc</function>, at
least not while you are connected to SPI. If you try, the object
will be deallocated by <function>SPI_finish</function>, and your
- procedure will not work reliably. To solve this problem, use
+ C function will not work reliably. To solve this problem, use
<function>SPI_palloc</function> to allocate memory for your return
object. <function>SPI_palloc</function> allocates memory in the
<quote>upper executor context</quote>, that is, the memory context
that was current when <function>SPI_connect</function> was called,
which is precisely the right context for a value returned from your
- procedure. Several of the other utility procedures described in
+ C function. Several of the other utility functions described in
this section also return objects created in the upper executor context.
</para>
<para>
When <function>SPI_connect</function> is called, the private
- context of the procedure, which is created by
+ context of the C function, which is created by
<function>SPI_connect</function>, is made the current context. All
allocations made by <function>palloc</function>,
<function>repalloc</function>, or SPI utility functions (except as
described in this section) are made in this context. When a
- procedure disconnects from the SPI manager (via
+ C function disconnects from the SPI manager (via
<function>SPI_finish</function>) the current context is restored to
the upper executor context, and all allocations made in the
- procedure memory context are freed and cannot be used any more.
+ C function memory context are freed and cannot be used any more.
</para>
<!-- *********************************************** -->
@@ -4263,12 +4256,12 @@ <title>Description</title>
</para>
<para>
- This function is useful if a SPI procedure needs to execute
+ This function is useful if an SPI-using C function needs to execute
multiple commands and does not want to keep the results of earlier
commands around until it ends. Note that any unfreed row sets will
be freed anyway at <function>SPI_finish</function>.
Also, if a subtransaction is started and then aborted within execution
- of a SPI procedure, SPI automatically frees any row sets created while
+ of an SPI-using C function, SPI automatically frees any row sets created while
the subtransaction was running.
</para>
@@ -4373,9 +4366,9 @@ <title>Transaction Management</title>
is part of some SQL command will probably result in obscure internal errors
or crashes. The interface functions presented here are primarily intended
to be used by procedural language implementations to support transaction
- management in procedures that are invoked by the <command>CALL</command>
+ management in SQL-level procedures that are invoked by the <command>CALL</command>
command, taking the context of the <command>CALL</command> invocation into
- account. SPI procedures implemented in C can implement the same logic, but
+ account. SPI-using procedures implemented in C can implement the same logic, but
the details of that are beyond the scope of this documentation.
</para>
@@ -4487,7 +4480,7 @@ <title>Description</title>
<function>SPI_start_transaction</function> starts a new transaction. It
can only be called after <function>SPI_commit</function>
or <function>SPI_rollback</function>, as there is no transaction active at
- that point. Normally, when an SPI procedure is called, there is already a
+ that point. Normally, when an SPI-using procedure is called, there is already a
transaction active, so attempting to start another one before closing out
the current one will result in an error.
</para>
@@ -4566,7 +4559,7 @@ <title>Examples</title>
<para>
This section contains a very simple example of SPI usage. The
- procedure <function>execq</function> takes an SQL command as its
+ C function <function>execq</function> takes an SQL command as its
first argument and a row count as its second, executes the command
using <function>SPI_exec</function> and returns the number of rows
that were processed by the command. You can find more complex
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
index 9f5c0c3fb2..f7713e8aba 100644
--- a/doc/src/sgml/xindex.sgml
+++ b/doc/src/sgml/xindex.sgml
@@ -50,7 +50,7 @@ <title>Index Methods and Operator Classes</title>
<literal>WHERE</literal>-clause operators that can be used with an index
(i.e., can be converted into an index-scan qualification). An
operator class can also specify some <firstterm>support
- procedures</firstterm> that are needed by the internal operations of the
+ function</firstterm> that are needed by the internal operations of the
index method, but do not directly correspond to any
<literal>WHERE</literal>-clause operator that can be used with the index.
</para>
diff --git a/doc/src/sgml/xplang.sgml b/doc/src/sgml/xplang.sgml
index 4b52210459..db765b4644 100644
--- a/doc/src/sgml/xplang.sgml
+++ b/doc/src/sgml/xplang.sgml
@@ -146,7 +146,7 @@ <title>Installing Procedural Languages</title>
the language does not grant access to data that the user would
not otherwise have. Trusted languages are designed for ordinary
database users (those without superuser privilege) and allows them
- to safely create functions and trigger
+ to safely create functions and
procedures. Since PL functions are executed inside the database
server, the <literal>TRUSTED</literal> flag should only be given
for languages that do not allow access to database server
@@ -206,7 +206,7 @@ <title>Manual Installation of <application>PL/Perl</application></title>
VALIDATOR plperl_validator;
</programlisting>
then defines that the previously declared functions
- should be invoked for functions and trigger procedures where the
+ should be invoked for functions and procedures where the
language attribute is <literal>plperl</literal>.
</para>
</example>
diff --git a/src/backend/access/gin/ginvalidate.c b/src/backend/access/gin/ginvalidate.c
index 1035be4463..1922260b75 100644
--- a/src/backend/access/gin/ginvalidate.c
+++ b/src/backend/access/gin/ginvalidate.c
@@ -90,7 +90,7 @@ ginvalidate(Oid opclassoid)
{
ereport(INFO,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types",
+ errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",
opfamilyname, "gin",
format_procedure(procform->amproc))));
result = false;
diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c
index dd87dad386..c300e52ca5 100644
--- a/src/backend/access/gist/gistvalidate.c
+++ b/src/backend/access/gist/gistvalidate.c
@@ -90,7 +90,7 @@ gistvalidate(Oid opclassoid)
{
ereport(INFO,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types",
+ errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",
opfamilyname, "gist",
format_procedure(procform->amproc))));
result = false;
diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c
index 4e485cc4b3..7c9b2cfc9e 100644
--- a/src/backend/access/hash/hashutil.c
+++ b/src/backend/access/hash/hashutil.c
@@ -73,10 +73,10 @@ _hash_checkqual(IndexScanDesc scan, IndexTuple itup)
}
/*
- * _hash_datum2hashkey -- given a Datum, call the index's hash procedure
+ * _hash_datum2hashkey -- given a Datum, call the index's hash function
*
* The Datum is assumed to be of the index's column type, so we can use the
- * "primary" hash procedure that's tracked for us by the generic index code.
+ * "primary" hash function that's tracked for us by the generic index code.
*/
uint32
_hash_datum2hashkey(Relation rel, Datum key)
diff --git a/src/backend/access/hash/hashvalidate.c b/src/backend/access/hash/hashvalidate.c
index 513a3bbc4c..aac148fd35 100644
--- a/src/backend/access/hash/hashvalidate.c
+++ b/src/backend/access/hash/hashvalidate.c
@@ -96,7 +96,7 @@ hashvalidate(Oid opclassoid)
{
ereport(INFO,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types",
+ errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",
opfamilyname, "hash",
format_procedure(procform->amproc))));
result = false;
@@ -182,7 +182,7 @@ hashvalidate(Oid opclassoid)
result = false;
}
- /* There should be relevant hash procedures for each datatype */
+ /* There should be relevant hash functions for each datatype */
if (!list_member_oid(hashabletypes, oprform->amoplefttype) ||
!list_member_oid(hashabletypes, oprform->amoprighttype))
{
diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c
index 619c357115..c7acc7fc02 100644
--- a/src/backend/access/spgist/spgvalidate.c
+++ b/src/backend/access/spgist/spgvalidate.c
@@ -96,7 +96,7 @@ spgvalidate(Oid opclassoid)
{
ereport(INFO,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types",
+ errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types",
opfamilyname, "spgist",
format_procedure(procform->amproc))));
result = false;
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index e4b1369f19..3b5c90e3f4 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -517,7 +517,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
if (item->number <= 0 || item->number > maxProcNumber)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("invalid procedure number %d,"
+ errmsg("invalid function number %d,"
" must be between 1 and %d",
item->number, maxProcNumber)));
funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
@@ -891,7 +891,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
if (item->number <= 0 || item->number > maxProcNumber)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("invalid procedure number %d,"
+ errmsg("invalid function number %d,"
" must be between 1 and %d",
item->number, maxProcNumber)));
funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
@@ -986,7 +986,7 @@ AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
if (item->number <= 0 || item->number > maxProcNumber)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("invalid procedure number %d,"
+ errmsg("invalid function number %d,"
" must be between 1 and %d",
item->number, maxProcNumber)));
processTypesSpec(item->class_args, &lefttype, &righttype);
@@ -1141,11 +1141,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
if (procform->pronargs != 2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree comparison procedures must have two arguments")));
+ errmsg("btree comparison functions must have two arguments")));
if (procform->prorettype != INT4OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree comparison procedures must return integer")));
+ errmsg("btree comparison functions must return integer")));
/*
* If lefttype/righttype isn't specified, use the proc's input
@@ -1162,11 +1162,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
procform->proargtypes.values[0] != INTERNALOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree sort support procedures must accept type \"internal\"")));
+ errmsg("btree sort support functions must accept type \"internal\"")));
if (procform->prorettype != VOIDOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree sort support procedures must return void")));
+ errmsg("btree sort support functions must return void")));
/*
* Can't infer lefttype/righttype from proc, so use default rule
@@ -1177,11 +1177,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
if (procform->pronargs != 5)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree in_range procedures must have five arguments")));
+ errmsg("btree in_range functions must have five arguments")));
if (procform->prorettype != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("btree in_range procedures must return boolean")));
+ errmsg("btree in_range functions must return boolean")));
/*
* If lefttype/righttype isn't specified, use the proc's input
@@ -1200,22 +1200,22 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
if (procform->pronargs != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("hash procedure 1 must have one argument")));
+ errmsg("hash function 1 must have one argument")));
if (procform->prorettype != INT4OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("hash procedure 1 must return integer")));
+ errmsg("hash function 1 must return integer")));
}
else if (member->number == HASHEXTENDED_PROC)
{
if (procform->pronargs != 2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("hash procedure 2 must have two arguments")));
+ errmsg("hash function 2 must have two arguments")));
if (procform->prorettype != INT8OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("hash procedure 2 must return bigint")));
+ errmsg("hash function 2 must return bigint")));
}
/*
@@ -1240,7 +1240,7 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype))
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("associated data types must be specified for index support procedure")));
+ errmsg("associated data types must be specified for index support function")));
ReleaseSysCache(proctup);
}
@@ -1265,7 +1265,7 @@ addFamilyMember(List **list, OpFamilyMember *member, bool isProc)
if (isProc)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("procedure number %d for (%s,%s) appears more than once",
+ errmsg("function number %d for (%s,%s) appears more than once",
member->number,
format_type_be(member->lefttype),
format_type_be(member->righttype))));
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 80d8338b96..4f7e93fe02 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3907,7 +3907,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("always"),
gettext_noop("disabled"),
gettext_noop("Enabled"),
- gettext_noop("Procedure"),
+ gettext_noop("Function"),
gettext_noop("Tags"));
if (verbose)
appendPQExpBuffer(&buf,
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index d6c306e969..543d802949 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -263,7 +263,7 @@ typedef struct HashMetaPageData
* allocated */
uint32 hashm_firstfree; /* lowest-number free ovflpage (bit#) */
uint32 hashm_nmaps; /* number of bitmap pages */
- RegProcedure hashm_procid; /* hash procedure id from pg_proc */
+ RegProcedure hashm_procid; /* hash function id from pg_proc */
uint32 hashm_spares[HASH_MAX_SPLITPOINTS]; /* spare pages before each
* splitpoint */
BlockNumber hashm_mapp[HASH_MAX_BITMAPS]; /* blknos of ovfl bitmaps */
@@ -338,15 +338,15 @@ typedef HashMetaPageData *HashMetaPage;
/*
* When a new operator class is declared, we require that the user supply
- * us with an amproc procedure for hashing a key of the new type, returning
- * a 32-bit hash value. We call this the "standard" hash procedure. We
- * also allow an optional "extended" hash procedure which accepts a salt and
+ * us with an amproc function for hashing a key of the new type, returning
+ * a 32-bit hash value. We call this the "standard" hash function. We
+ * also allow an optional "extended" hash function which accepts a salt and
* returns a 64-bit hash value. This is highly recommended but, for reasons
* of backward compatibility, optional.
*
* When the salt is 0, the low 32 bits of the value returned by the extended
- * hash procedure should match the value that would have been returned by the
- * standard hash procedure.
+ * hash function should match the value that would have been returned by the
+ * standard hash function.
*/
#define HASHSTANDARD_PROC 1
#define HASHEXTENDED_PROC 2
diff --git a/src/test/regress/expected/alter_generic.out b/src/test/regress/expected/alter_generic.out
index f24a17f40e..6faa9d739d 100644
--- a/src/test/regress/expected/alter_generic.out
+++ b/src/test/regress/expected/alter_generic.out
@@ -354,9 +354,9 @@ ERROR: invalid operator number 0, must be between 1 and 5
ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 < ; -- operator without argument types
ERROR: operator argument types must be specified in ALTER OPERATOR FAMILY
ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2); -- function number should be between 1 and 5
-ERROR: invalid procedure number 0, must be between 1 and 3
+ERROR: invalid function number 0, must be between 1 and 3
ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 6 btint42cmp(int4, int2); -- function number should be between 1 and 5
-ERROR: invalid procedure number 6, must be between 1 and 3
+ERROR: invalid function number 6, must be between 1 and 3
ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage; -- Ensure STORAGE is not a part of ALTER OPERATOR FAMILY
ERROR: STORAGE cannot be specified in ALTER OPERATOR FAMILY
DROP OPERATOR FAMILY alt_opf4 USING btree;
@@ -412,7 +412,7 @@ BEGIN TRANSACTION;
CREATE OPERATOR FAMILY alt_opf12 USING btree;
CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2);
-ERROR: btree comparison procedures must return integer
+ERROR: btree comparison functions must return integer
DROP OPERATOR FAMILY alt_opf12 USING btree;
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
@@ -421,7 +421,7 @@ BEGIN TRANSACTION;
CREATE OPERATOR FAMILY alt_opf13 USING hash;
CREATE FUNCTION fn_opf13 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4);
-ERROR: hash procedure 1 must return integer
+ERROR: hash function 1 must return integer
DROP OPERATOR FAMILY alt_opf13 USING hash;
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
@@ -430,7 +430,7 @@ BEGIN TRANSACTION;
CREATE OPERATOR FAMILY alt_opf14 USING btree;
CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4);
-ERROR: btree comparison procedures must have two arguments
+ERROR: btree comparison functions must have two arguments
DROP OPERATOR FAMILY alt_opf14 USING btree;
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
@@ -439,7 +439,7 @@ BEGIN TRANSACTION;
CREATE OPERATOR FAMILY alt_opf15 USING hash;
CREATE FUNCTION fn_opf15 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2);
-ERROR: hash procedure 1 must have one argument
+ERROR: hash function 1 must have one argument
DROP OPERATOR FAMILY alt_opf15 USING hash;
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
@@ -447,7 +447,7 @@ ROLLBACK;
-- without defining left / right type in ALTER OPERATOR FAMILY ... ADD FUNCTION
CREATE OPERATOR FAMILY alt_opf16 USING gist;
ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2);
-ERROR: associated data types must be specified for index support procedure
+ERROR: associated data types must be specified for index support function
DROP OPERATOR FAMILY alt_opf16 USING gist;
-- Should fail. duplicate operator number / function number in ALTER OPERATOR FAMILY ... ADD FUNCTION
CREATE OPERATOR FAMILY alt_opf17 USING btree;
@@ -464,7 +464,7 @@ ALTER OPERATOR FAMILY alt_opf17 USING btree ADD
OPERATOR 5 > (int4, int2) ,
FUNCTION 1 btint42cmp(int4, int2) ,
FUNCTION 1 btint42cmp(int4, int2); -- procedure 1 appears twice in same statement
-ERROR: procedure number 1 for (integer,smallint) appears more than once
+ERROR: function number 1 for (integer,smallint) appears more than once
ALTER OPERATOR FAMILY alt_opf17 USING btree ADD
OPERATOR 1 < (int4, int2) ,
OPERATOR 2 <= (int4, int2) ,
diff --git a/src/test/regress/expected/create_operator.out b/src/test/regress/expected/create_operator.out
index e35eb09250..fd8b37fff5 100644
--- a/src/test/regress/expected/create_operator.out
+++ b/src/test/regress/expected/create_operator.out
@@ -185,11 +185,11 @@ CREATE OPERATOR ===
(
"Leftarg" = box,
"Rightarg" = box,
- "Procedure" = area_equal_procedure,
+ "Procedure" = area_equal_function,
"Commutator" = ===,
"Negator" = !==,
- "Restrict" = area_restriction_procedure,
- "Join" = area_join_procedure,
+ "Restrict" = area_restriction_function,
+ "Join" = area_join_function,
"Hashes",
"Merges"
);
diff --git a/src/test/regress/sql/create_operator.sql b/src/test/regress/sql/create_operator.sql
index c71765f9be..9edf32b3f8 100644
--- a/src/test/regress/sql/create_operator.sql
+++ b/src/test/regress/sql/create_operator.sql
@@ -189,11 +189,11 @@ CREATE OPERATOR ===
(
"Leftarg" = box,
"Rightarg" = box,
- "Procedure" = area_equal_procedure,
+ "Procedure" = area_equal_function,
"Commutator" = ===,
"Negator" = !==,
- "Restrict" = area_restriction_procedure,
- "Join" = area_join_procedure,
+ "Restrict" = area_restriction_function,
+ "Join" = area_join_function,
"Hashes",
"Merges"
);
--
2.18.0
0002-Change-PROCEDURE-to-FUNCTION-in-CREATE-OPERATOR-synt.patchtext/plain; charset=UTF-8; name=0002-Change-PROCEDURE-to-FUNCTION-in-CREATE-OPERATOR-synt.patch; x-mac-creator=0; x-mac-type=0Download
From 7f98dc8385dd1822bc3a4eec502d1aec941c58ae Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 15 Aug 2018 18:05:46 +0200
Subject: [PATCH 2/3] Change PROCEDURE to FUNCTION in CREATE OPERATOR syntax
Since procedures are now a different thing from functions, change the
CREATE OPERATOR syntax to use FUNCTION in the clause that specifies the
function. PROCEDURE is still accepted for compatibility.
---
doc/src/sgml/extend.sgml | 2 +-
doc/src/sgml/ref/create_operator.sgml | 12 ++++++++++--
doc/src/sgml/xoper.sgml | 4 ++--
src/backend/commands/operatorcmds.c | 19 +++++++++++--------
src/bin/pg_dump/pg_dump.c | 2 +-
src/test/regress/expected/create_operator.out | 6 +++---
src/test/regress/sql/create_operator.sql | 2 +-
7 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
index a3cb064131..d5731621e7 100644
--- a/doc/src/sgml/extend.sgml
+++ b/doc/src/sgml/extend.sgml
@@ -1015,7 +1015,7 @@ <title>Extension Example</title>
CREATE OR REPLACE FUNCTION pair(text, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';
-CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, PROCEDURE = pair);
+CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);
-- "SET search_path" is easy to get right, but qualified names perform better.
CREATE OR REPLACE FUNCTION lower(pair)
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
index c8263437ab..d5c385c087 100644
--- a/doc/src/sgml/ref/create_operator.sgml
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -22,7 +22,7 @@
<refsynopsisdiv>
<synopsis>
CREATE OPERATOR <replaceable>name</replaceable> (
- PROCEDURE = <replaceable class="parameter">function_name</replaceable>
+ {FUNCTION|PROCEDURE} = <replaceable class="parameter">function_name</replaceable>
[, LEFTARG = <replaceable class="parameter">left_type</replaceable> ] [, RIGHTARG = <replaceable class="parameter">right_type</replaceable> ]
[, COMMUTATOR = <replaceable class="parameter">com_op</replaceable> ] [, NEGATOR = <replaceable class="parameter">neg_op</replaceable> ]
[, RESTRICT = <replaceable class="parameter">res_proc</replaceable> ] [, JOIN = <replaceable class="parameter">join_proc</replaceable> ]
@@ -99,6 +99,14 @@ <title>Description</title>
of arguments (either one or two) of the indicated types.
</para>
+ <para>
+ In the syntax of <literal>CREATE OPERATOR</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function, not
+ a procedure. The use of the keyword <literal>PROCEDURE</literal> here is
+ historical and deprecated.
+ </para>
+
<para>
The other clauses specify optional operator optimization clauses.
Their meaning is detailed in <xref linkend="xoper-optimization"/>.
@@ -264,7 +272,7 @@ <title>Examples</title>
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
- PROCEDURE = area_equal_function,
+ FUNCTION = area_equal_function,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = area_restriction_function,
diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml
index 2aa7cf9b64..2f5560ac50 100644
--- a/doc/src/sgml/xoper.sgml
+++ b/doc/src/sgml/xoper.sgml
@@ -44,7 +44,7 @@ <title>User-defined Operators</title>
CREATE OPERATOR + (
leftarg = complex,
rightarg = complex,
- procedure = complex_add,
+ function = complex_add,
commutator = +
);
</programlisting>
@@ -66,7 +66,7 @@ <title>User-defined Operators</title>
<para>
We've shown how to create a binary operator here. To create unary
operators, just omit one of <literal>leftarg</literal> (for left unary) or
- <literal>rightarg</literal> (for right unary). The <literal>procedure</literal>
+ <literal>rightarg</literal> (for right unary). The <literal>function</literal>
clause and the argument clauses are the only required items in
<command>CREATE OPERATOR</command>. The <literal>commutator</literal>
clause shown in the example is an optional hint to the query
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index f0da4c5279..5e5434ec03 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -21,7 +21,7 @@
* NOTES
* These things must be defined and committed in the following order:
* "create function":
- * input/output, recv/send procedures
+ * input/output, recv/send functions
* "create type":
* type
* "create operator":
@@ -79,8 +79,8 @@ DefineOperator(List *names, List *parameters)
Oid rettype;
List *commutatorName = NIL; /* optional commutator operator name */
List *negatorName = NIL; /* optional negator operator name */
- List *restrictionName = NIL; /* optional restrict. sel. procedure */
- List *joinName = NIL; /* optional join sel. procedure */
+ List *restrictionName = NIL; /* optional restrict. sel. function */
+ List *joinName = NIL; /* optional join sel. function */
Oid functionOid; /* functions converted to OID */
Oid restrictionOid;
Oid joinOid;
@@ -120,6 +120,8 @@ DefineOperator(List *names, List *parameters)
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SETOF type not allowed for operator argument")));
}
+ else if (strcmp(defel->defname, "function") == 0)
+ functionName = defGetQualifiedName(defel);
else if (strcmp(defel->defname, "procedure") == 0)
functionName = defGetQualifiedName(defel);
else if (strcmp(defel->defname, "commutator") == 0)
@@ -159,7 +161,7 @@ DefineOperator(List *names, List *parameters)
if (functionName == NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("operator procedure must be specified")));
+ errmsg("operator function must be specified")));
/* Transform type names to type OIDs */
if (typeName1)
@@ -245,8 +247,8 @@ DefineOperator(List *names, List *parameters)
functionOid, /* function for operator */
commutatorName, /* optional commutator operator name */
negatorName, /* optional negator operator name */
- restrictionOid, /* optional restrict. sel. procedure */
- joinOid, /* optional join sel. procedure name */
+ restrictionOid, /* optional restrict. sel. function */
+ joinOid, /* optional join sel. function name */
canMerge, /* operator merges */
canHash); /* operator hashes */
}
@@ -393,10 +395,10 @@ AlterOperator(AlterOperatorStmt *stmt)
Datum values[Natts_pg_operator];
bool nulls[Natts_pg_operator];
bool replaces[Natts_pg_operator];
- List *restrictionName = NIL; /* optional restrict. sel. procedure */
+ List *restrictionName = NIL; /* optional restrict. sel. function */
bool updateRestriction = false;
Oid restrictionOid;
- List *joinName = NIL; /* optional join sel. procedure */
+ List *joinName = NIL; /* optional join sel. function */
bool updateJoin = false;
Oid joinOid;
@@ -436,6 +438,7 @@ AlterOperator(AlterOperatorStmt *stmt)
*/
else if (strcmp(defel->defname, "leftarg") == 0 ||
strcmp(defel->defname, "rightarg") == 0 ||
+ strcmp(defel->defname, "function") == 0 ||
strcmp(defel->defname, "procedure") == 0 ||
strcmp(defel->defname, "commutator") == 0 ||
strcmp(defel->defname, "negator") == 0 ||
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index e1d27bb3ac..a7883d3fd9 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12396,7 +12396,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
oprregproc = convertRegProcReference(fout, oprcode);
if (oprregproc)
{
- appendPQExpBuffer(details, " PROCEDURE = %s", oprregproc);
+ appendPQExpBuffer(details, " FUNCTION = %s", oprregproc);
free(oprregproc);
}
diff --git a/src/test/regress/expected/create_operator.out b/src/test/regress/expected/create_operator.out
index fd8b37fff5..77237f4850 100644
--- a/src/test/regress/expected/create_operator.out
+++ b/src/test/regress/expected/create_operator.out
@@ -4,7 +4,7 @@
CREATE OPERATOR ## (
leftarg = path,
rightarg = path,
- procedure = path_inter,
+ function = path_inter,
commutator = ##
);
CREATE OPERATOR <% (
@@ -107,7 +107,7 @@ ERROR: at least one of leftarg or rightarg must be specified
CREATE OPERATOR #@%# (
leftarg = int8
);
-ERROR: operator procedure must be specified
+ERROR: operator function must be specified
-- Should fail. CREATE OPERATOR requires USAGE on TYPE
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op3;
@@ -202,4 +202,4 @@ WARNING: operator attribute "Restrict" not recognized
WARNING: operator attribute "Join" not recognized
WARNING: operator attribute "Hashes" not recognized
WARNING: operator attribute "Merges" not recognized
-ERROR: operator procedure must be specified
+ERROR: operator function must be specified
diff --git a/src/test/regress/sql/create_operator.sql b/src/test/regress/sql/create_operator.sql
index 9edf32b3f8..625e9b9748 100644
--- a/src/test/regress/sql/create_operator.sql
+++ b/src/test/regress/sql/create_operator.sql
@@ -5,7 +5,7 @@
CREATE OPERATOR ## (
leftarg = path,
rightarg = path,
- procedure = path_inter,
+ function = path_inter,
commutator = ##
);
--
2.18.0
0003-Change-PROCEDURE-to-FUNCTION-in-CREATE-TRIGGER-synta.patchtext/plain; charset=UTF-8; name=0003-Change-PROCEDURE-to-FUNCTION-in-CREATE-TRIGGER-synta.patch; x-mac-creator=0; x-mac-type=0Download
From 88e785538d8a1fb9e7c007b46943de3dbd13675f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 15 Aug 2018 23:08:34 +0200
Subject: [PATCH 3/3] Change PROCEDURE to FUNCTION in CREATE TRIGGER syntax
Since procedures are now a different thing from functions, change the
CREATE TRIGGER and CREATE EVENT TRIGGER syntax to use FUNCTION in the
clause that specifies the function. PROCEDURE is still accepted for
compatibility.
pg_dump and ruleutils.c output is not changed yet, because that would
require a change in information_schema.sql and thus a catversion change.
---
doc/src/sgml/ddl.sgml | 2 +-
doc/src/sgml/event-trigger.sgml | 4 ++--
doc/src/sgml/func.sgml | 6 +++---
doc/src/sgml/information_schema.sgml | 2 +-
doc/src/sgml/lo.sgml | 2 +-
doc/src/sgml/plperl.sgml | 4 ++--
doc/src/sgml/plpgsql.sgml | 16 +++++++--------
doc/src/sgml/pltcl.sgml | 4 ++--
doc/src/sgml/ref/create_event_trigger.sgml | 12 +++++++++--
doc/src/sgml/ref/create_trigger.sgml | 24 ++++++++++++++--------
doc/src/sgml/tcn.sgml | 2 +-
doc/src/sgml/textsearch.sgml | 4 ++--
doc/src/sgml/trigger.sgml | 4 ++--
src/backend/parser/gram.y | 9 ++++++--
src/test/regress/expected/triggers.out | 4 ++--
src/test/regress/sql/triggers.sql | 4 ++--
16 files changed, 62 insertions(+), 41 deletions(-)
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index 6aa035188f..5ae3cacbf0 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -3580,7 +3580,7 @@ <title>Example</title>
<programlisting>
CREATE TRIGGER insert_measurement_trigger
BEFORE INSERT ON measurement
- FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();
+ FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();
</programlisting>
We must redefine the trigger function each month so that it always
diff --git a/doc/src/sgml/event-trigger.sgml b/doc/src/sgml/event-trigger.sgml
index be975d1399..d273dc5b58 100644
--- a/doc/src/sgml/event-trigger.sgml
+++ b/doc/src/sgml/event-trigger.sgml
@@ -1044,7 +1044,7 @@ <title>A Complete Event Trigger Example</title>
AS 'noddl' LANGUAGE C;
CREATE EVENT TRIGGER noddl ON ddl_command_start
- EXECUTE PROCEDURE noddl();
+ EXECUTE FUNCTION noddl();
</programlisting>
</para>
@@ -1129,7 +1129,7 @@ <title>A Table Rewrite Event Trigger Example</title>
CREATE EVENT TRIGGER no_rewrite_allowed
ON table_rewrite
- EXECUTE PROCEDURE no_rewrite();
+ EXECUTE FUNCTION no_rewrite();
</programlisting>
</para>
</sect1>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index c6f61ce2c0..eaf8fbdf62 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -20594,7 +20594,7 @@ <title>Trigger Functions</title>
<programlisting>
CREATE TRIGGER z_min_update
BEFORE UPDATE ON tablename
-FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger();
</programlisting>
In most cases, you would want to fire this trigger last for each row.
Bearing in mind that triggers fire in name order, you would then
@@ -20846,7 +20846,7 @@ <title>Processing Objects Dropped by a DDL Command</title>
$$;
CREATE EVENT TRIGGER test_event_trigger_for_drops
ON sql_drop
- EXECUTE PROCEDURE test_event_trigger_for_drops();
+ EXECUTE FUNCTION test_event_trigger_for_drops();
</programlisting>
</para>
</sect2>
@@ -20911,7 +20911,7 @@ <title>Table Rewrite information</title>
CREATE EVENT TRIGGER test_table_rewrite_oid
ON table_rewrite
- EXECUTE PROCEDURE test_event_trigger_table_rewrite_oid();
+ EXECUTE FUNCTION test_event_trigger_table_rewrite_oid();
</programlisting>
</para>
</sect2>
diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml
index 09ef2827f2..9a61aa8541 100644
--- a/doc/src/sgml/information_schema.sgml
+++ b/doc/src/sgml/information_schema.sgml
@@ -5793,7 +5793,7 @@ <title><literal>triggers</literal> Columns</title>
<entry><type>character_data</type></entry>
<entry>
Statement that is executed by the trigger (currently always
- <literal>EXECUTE PROCEDURE
+ <literal>EXECUTE FUNCTION
<replaceable>function</replaceable>(...)</literal>)
</entry>
</row>
diff --git a/doc/src/sgml/lo.sgml b/doc/src/sgml/lo.sgml
index ab8d192bc1..cce37932ec 100644
--- a/doc/src/sgml/lo.sgml
+++ b/doc/src/sgml/lo.sgml
@@ -70,7 +70,7 @@ <title>How to Use It</title>
CREATE TABLE image (title text, raster lo);
CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
- FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
+ FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);
</programlisting>
<para>
diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml
index 6296a226b6..967efba3b5 100644
--- a/doc/src/sgml/plperl.sgml
+++ b/doc/src/sgml/plperl.sgml
@@ -1300,7 +1300,7 @@ <title>PL/Perl Triggers</title>
CREATE TRIGGER test_valid_id_trig
BEFORE INSERT OR UPDATE ON test
- FOR EACH ROW EXECUTE PROCEDURE valid_id();
+ FOR EACH ROW EXECUTE FUNCTION valid_id();
</programlisting>
</para>
</sect1>
@@ -1350,7 +1350,7 @@ <title>PL/Perl Event Triggers</title>
CREATE EVENT TRIGGER perl_a_snitch
ON ddl_command_start
- EXECUTE PROCEDURE perlsnitch();
+ EXECUTE FUNCTION perlsnitch();
</programlisting>
</para>
</sect1>
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index abe67fa50e..6b19f18dd8 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -4069,7 +4069,7 @@ <title>A <application>PL/pgSQL</application> Trigger Function</title>
$emp_stamp$ LANGUAGE plpgsql;
CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
- FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
+ FOR EACH ROW EXECUTE FUNCTION emp_stamp();
</programlisting>
</example>
@@ -4124,7 +4124,7 @@ <title>A <application>PL/pgSQL</application> Trigger Function For Auditing</titl
CREATE TRIGGER emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
- FOR EACH ROW EXECUTE PROCEDURE process_emp_audit();
+ FOR EACH ROW EXECUTE FUNCTION process_emp_audit();
</programlisting>
</example>
@@ -4203,7 +4203,7 @@ <title>A <application>PL/pgSQL</application> View Trigger Function For Auditing<
CREATE TRIGGER emp_audit
INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view
- FOR EACH ROW EXECUTE PROCEDURE update_emp_view();
+ FOR EACH ROW EXECUTE FUNCTION update_emp_view();
</programlisting>
</example>
@@ -4348,7 +4348,7 @@ <title>A <application>PL/pgSQL</application> Trigger Function For Maintaining A
CREATE TRIGGER maint_sales_summary_bytime
AFTER INSERT OR UPDATE OR DELETE ON sales_fact
- FOR EACH ROW EXECUTE PROCEDURE maint_sales_summary_bytime();
+ FOR EACH ROW EXECUTE FUNCTION maint_sales_summary_bytime();
INSERT INTO sales_fact VALUES(1,1,1,10,3,15);
INSERT INTO sales_fact VALUES(1,2,1,20,5,35);
@@ -4425,15 +4425,15 @@ <title>Auditing with Transition Tables</title>
CREATE TRIGGER emp_audit_ins
AFTER INSERT ON emp
REFERENCING NEW TABLE AS new_table
- FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit();
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
CREATE TRIGGER emp_audit_upd
AFTER UPDATE ON emp
REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
- FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit();
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
CREATE TRIGGER emp_audit_del
AFTER DELETE ON emp
REFERENCING OLD TABLE AS old_table
- FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit();
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
</programlisting>
</example>
@@ -4498,7 +4498,7 @@ <title>A <application>PL/pgSQL</application> Event Trigger Function</title>
END;
$$ LANGUAGE plpgsql;
-CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE PROCEDURE snitch();
+CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
</programlisting>
</example>
</sect2>
diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml
index 97906a67df..61c059a224 100644
--- a/doc/src/sgml/pltcl.sgml
+++ b/doc/src/sgml/pltcl.sgml
@@ -789,7 +789,7 @@ <title>Trigger Functions in PL/Tcl</title>
CREATE TABLE mytab (num integer, description text, modcnt integer);
CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
- FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
+ FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');
</programlisting>
Notice that the trigger function itself does not know the column
@@ -852,7 +852,7 @@ <title>Event Trigger Functions in PL/Tcl</title>
elog NOTICE "tclsnitch: $TG_event $TG_tag"
$$ LANGUAGE pltcl;
-CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE PROCEDURE tclsnitch();
+CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitch();
</programlisting>
</para>
</sect1>
diff --git a/doc/src/sgml/ref/create_event_trigger.sgml b/doc/src/sgml/ref/create_event_trigger.sgml
index 396d82118e..52ba746166 100644
--- a/doc/src/sgml/ref/create_event_trigger.sgml
+++ b/doc/src/sgml/ref/create_event_trigger.sgml
@@ -24,7 +24,7 @@
CREATE EVENT TRIGGER <replaceable class="parameter">name</replaceable>
ON <replaceable class="parameter">event</replaceable>
[ WHEN <replaceable class="parameter">filter_variable</replaceable> IN (filter_value [, ... ]) [ AND ... ] ]
- EXECUTE PROCEDURE <replaceable class="parameter">function_name</replaceable>()
+ EXECUTE { FUNCTION | PROCEDURE } <replaceable class="parameter">function_name</replaceable>()
</synopsis>
</refsynopsisdiv>
@@ -98,6 +98,14 @@ <title>Parameters</title>
A user-supplied function that is declared as taking no argument and
returning type <literal>event_trigger</literal>.
</para>
+
+ <para>
+ In the syntax of <literal>CREATE EVENT TRIGGER</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <literal>PROCEDURE</literal>
+ here is historical and deprecated.
+ </para>
</listitem>
</varlistentry>
@@ -136,7 +144,7 @@ <title>Examples</title>
$$;
CREATE EVENT TRIGGER abort_ddl ON ddl_command_start
- EXECUTE PROCEDURE abort_any_command();
+ EXECUTE FUNCTION abort_any_command();
</programlisting></para>
</refsect1>
diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml
index b2dddafb46..6514ffc6ae 100644
--- a/doc/src/sgml/ref/create_trigger.sgml
+++ b/doc/src/sgml/ref/create_trigger.sgml
@@ -33,7 +33,7 @@
[ REFERENCING { { OLD | NEW } TABLE [ AS ] <replaceable class="parameter">transition_relation_name</replaceable> } [ ... ] ]
[ FOR [ EACH ] { ROW | STATEMENT } ]
[ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
- EXECUTE PROCEDURE <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">arguments</replaceable> )
+ EXECUTE { FUNCTION | PROCEDURE } <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">arguments</replaceable> )
<phrase>where <replaceable class="parameter">event</replaceable> can be one of:</phrase>
@@ -401,6 +401,14 @@ <title>Parameters</title>
and returning type <literal>trigger</literal>, which is executed when
the trigger fires.
</para>
+
+ <para>
+ In the syntax of <literal>CREATE TRIGGER</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <literal>PROCEDURE</literal>
+ here is historical and deprecated.
+ </para>
</listitem>
</varlistentry>
@@ -555,7 +563,7 @@ <title>Examples</title>
CREATE TRIGGER check_update
BEFORE UPDATE ON accounts
FOR EACH ROW
- EXECUTE PROCEDURE check_account_update();
+ EXECUTE FUNCTION check_account_update();
</programlisting>
The same, but only execute the function if column <literal>balance</literal>
@@ -565,7 +573,7 @@ <title>Examples</title>
CREATE TRIGGER check_update
BEFORE UPDATE OF balance ON accounts
FOR EACH ROW
- EXECUTE PROCEDURE check_account_update();
+ EXECUTE FUNCTION check_account_update();
</programlisting>
This form only executes the function if column <literal>balance</literal>
@@ -576,7 +584,7 @@ <title>Examples</title>
BEFORE UPDATE ON accounts
FOR EACH ROW
WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
- EXECUTE PROCEDURE check_account_update();
+ EXECUTE FUNCTION check_account_update();
</programlisting>
Call a function to log updates of <literal>accounts</literal>, but only if
@@ -587,7 +595,7 @@ <title>Examples</title>
AFTER UPDATE ON accounts
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
- EXECUTE PROCEDURE log_account_update();
+ EXECUTE FUNCTION log_account_update();
</programlisting>
Execute the function <function>view_insert_row</function> for each row to insert
@@ -597,7 +605,7 @@ <title>Examples</title>
CREATE TRIGGER view_insert
INSTEAD OF INSERT ON my_view
FOR EACH ROW
- EXECUTE PROCEDURE view_insert_row();
+ EXECUTE FUNCTION view_insert_row();
</programlisting>
Execute the function <function>check_transfer_balances_to_zero</function> for each
@@ -609,7 +617,7 @@ <title>Examples</title>
AFTER INSERT ON transfer
REFERENCING NEW TABLE AS inserted
FOR EACH STATEMENT
- EXECUTE PROCEDURE check_transfer_balances_to_zero();
+ EXECUTE FUNCTION check_transfer_balances_to_zero();
</programlisting>
Execute the function <function>check_matching_pairs</function> for each row to
@@ -621,7 +629,7 @@ <title>Examples</title>
AFTER UPDATE ON paired_items
REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
FOR EACH ROW
- EXECUTE PROCEDURE check_matching_pairs();
+ EXECUTE FUNCTION check_matching_pairs();
</programlisting>
</para>
diff --git a/doc/src/sgml/tcn.sgml b/doc/src/sgml/tcn.sgml
index 8cc55efd29..aa2fe4f00a 100644
--- a/doc/src/sgml/tcn.sgml
+++ b/doc/src/sgml/tcn.sgml
@@ -47,7 +47,7 @@ <title>tcn</title>
CREATE TABLE
test=# create trigger tcndata_tcn_trigger
test-# after insert or update or delete on tcndata
-test-# for each row execute procedure triggered_change_notification();
+test-# for each row execute function triggered_change_notification();
CREATE TRIGGER
test=# listen tcn;
LISTEN
diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml
index 6df424c63e..800a94bb54 100644
--- a/doc/src/sgml/textsearch.sgml
+++ b/doc/src/sgml/textsearch.sgml
@@ -1884,7 +1884,7 @@ <title>Triggers for Automatic Updates</title>
);
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
-ON messages FOR EACH ROW EXECUTE PROCEDURE
+ON messages FOR EACH ROW EXECUTE FUNCTION
tsvector_update_trigger(tsv, 'pg_catalog.english', title, body);
INSERT INTO messages VALUES('title here', 'the body text is here');
@@ -1940,7 +1940,7 @@ <title>Triggers for Automatic Updates</title>
$$ LANGUAGE plpgsql;
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
- ON messages FOR EACH ROW EXECUTE PROCEDURE messages_trigger();
+ ON messages FOR EACH ROW EXECUTE FUNCTION messages_trigger();
</programlisting>
</para>
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
index c43dbc9786..be9c228448 100644
--- a/doc/src/sgml/trigger.sgml
+++ b/doc/src/sgml/trigger.sgml
@@ -871,10 +871,10 @@ <title>A Complete Trigger Example</title>
LANGUAGE C;
CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest
- FOR EACH ROW EXECUTE PROCEDURE trigf();
+ FOR EACH ROW EXECUTE FUNCTION trigf();
CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest
- FOR EACH ROW EXECUTE PROCEDURE trigf();
+ FOR EACH ROW EXECUTE FUNCTION trigf();
</programlisting>
</para>
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 90dfac2cb1..cda6895153 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5344,7 +5344,7 @@ CreateAmStmt: CREATE ACCESS METHOD name TYPE_P INDEX HANDLER handler_name
CreateTrigStmt:
CREATE TRIGGER name TriggerActionTime TriggerEvents ON
qualified_name TriggerReferencing TriggerForSpec TriggerWhen
- EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
+ EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
{
CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $3;
@@ -5366,7 +5366,7 @@ CreateTrigStmt:
| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
qualified_name OptConstrFromTable ConstraintAttributeSpec
FOR EACH ROW TriggerWhen
- EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
+ EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
{
CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $4;
@@ -5504,6 +5504,11 @@ TriggerWhen:
| /*EMPTY*/ { $$ = NULL; }
;
+FUNCTION_or_PROCEDURE:
+ FUNCTION
+ | PROCEDURE
+ ;
+
TriggerFuncArgs:
TriggerFuncArg { $$ = list_make1($1); }
| TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); }
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index bf271d536e..843c94094b 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -22,12 +22,12 @@ create unique index pkeys_i on pkeys (pkey1, pkey2);
create trigger check_fkeys_pkey_exist
before insert or update on fkeys
for each row
- execute procedure
+ execute function
check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2');
create trigger check_fkeys_pkey2_exist
before insert or update on fkeys
for each row
- execute procedure check_primary_key ('fkey3', 'fkeys2', 'pkey23');
+ execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23');
--
-- For fkeys2:
-- (fkey21, fkey22) --> pkeys (pkey1, pkey2)
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 7cfa5fdf92..451527dbd5 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -26,13 +26,13 @@
create trigger check_fkeys_pkey_exist
before insert or update on fkeys
for each row
- execute procedure
+ execute function
check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2');
create trigger check_fkeys_pkey2_exist
before insert or update on fkeys
for each row
- execute procedure check_primary_key ('fkey3', 'fkeys2', 'pkey23');
+ execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23');
--
-- For fkeys2:
--
2.18.0
On Fri, Aug 17, 2018 at 7:15 AM, Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
Attached are my proposed patches.
I take it that you propose all 3 for backpatch to v11?
--
Peter Geoghegan
On Aug 17, 2018, at 10:15 AM, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
Attached are my proposed patches. The first is the documentation
change, which basically just substitutes the words, with some occasional
rephrasing. And then patches to extend the syntaxes of CREATE OPERATOR,
CREATE TRIGGER, and CREATE EVENT TRIGGER to accept FUNCTION in place of
PROCEDURE. I decided to do that because with the adjustments from the
first patch, the documentation had become comically inconsistent in some
places and it was easier to just fix the underlying problem than to
explain the reasons for the inconsistencies everywhere. I didn't go
around change all the commands in contrib modules etc. to keep the patch
size under control. This could perhaps be done later.
Thank for going through this, I know it’s an arduous task.
I reviewed the patches, here are my comments.
Patch 1
======
Built ok. All tests passed. Manual checks passed. I would recommend
backpatching this to 11.
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index d6688e13f4..abe67fa50e 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -19,7 +19,7 @@ <title>Overview</title>
<itemizedlist>
<listitem>
<para>
- can be used to create functions and trigger procedures,
+ can be used to create functions and triggers,
</para>
Perhaps: “can be used to create functions used in queries and triggers” or
just “can be used to create functions and trigger functions.”
Similarly for:
diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml
index 01f6207d36..97906a67df 100644
--- a/doc/src/sgml/pltcl.sgml
+++ b/doc/src/sgml/pltcl.sgml
@@ -16,7 +16,7 @@ <title>PL/Tcl - Tcl Procedural Language</title>
<productname>PostgreSQL</productname> database system
that enables the <ulink url="http://www.tcl.tk/">
Tcl language</ulink> to be used to write functions and
- trigger procedures.
+ triggers.
</para>
I’d be more specific, as the trigger executes the trigger function.
Patch 2
======
Built ok. Tests passed. Manual tests passed. Did a few pg_dump / restore
scenarios as well.
Code looked ok to me, though I’d consider adding a comment in
“operatorcmds.c" about how function / procedure are interchangeable,
which is why both outcomes are identical:
@@ -120,6 +120,8 @@ DefineOperator(List *names, List *parameters)
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SETOF type not allowed for operator argument")));
}
+ else if (strcmp(defel->defname, "function") == 0)
+ functionName = defGetQualifiedName(defel);
else if (strcmp(defel->defname, "procedure") == 0)
functionName = defGetQualifiedName(defel);
else if (strcmp(defel->defname, "commutator") == 0)
I can also make arguments both ways about backpatching Patch 2 to v11. It
would be less confusing for users (“I have to create a procedure to create an
operator??”), though the type of user who is creating a custom operator is more
sophisticated.
I think it would be better to backpatch to v11, but I can be convinced otherwise
by a strong argument.
Patch 3
======
I was trying to determine if changing to “EXECUTE FUNCTION” would be part
of the SQL standard, which with some (poorly done?) searching it looks like it is.
Before commenting further, this patch would give me the most cause-for-pause about
backporting to v11 at this point as triggers are highly utilized. Like Patch 2 I can
make arguments for both, but I need to think about it a bit more.
Anyway, builds ok, tests passed.
When manually testing, I noticed pg_dump still outputs “EXECUTE PROCEDURE”
as part of the trigger syntax. Here is the example I used to produce it:
CREATE TABLE a (
x int GENERATED BY DEFAULT AS iDENTITY PRIMARY KEY,
y int NOT NULL
);
CREATE TABLE b (
a_id int PRIMARY KEY REFERENCES a (x) UNIQUE,
created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE OR REPLACE FUNCTION a_insrt ()
RETURNS trigger
AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO b VALUES (NEW.x, CURRENT_TIMESTAMP);
RETURN NEW;
END IF;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER a_insrt
AFTER INSERT ON a
FOR EACH ROW
EXECUTE FUNCTION a_insrt();
Other than that, the patch looked ok to me.
Thanks again for pulling all of this together,
Jonathan
On 17/08/2018 21:57, Peter Geoghegan wrote:
On Fri, Aug 17, 2018 at 7:15 AM, Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:Attached are my proposed patches.
I take it that you propose all 3 for backpatch to v11?
yes
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 18/08/2018 19:37, Jonathan S. Katz wrote:
I reviewed the patches, here are my comments.
Committed all three with some adjustments. Thanks.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On Aug 22, 2018, at 9:15 AM, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 18/08/2018 19:37, Jonathan S. Katz wrote:
I reviewed the patches, here are my comments.
Committed all three with some adjustments. Thanks.
Awesome, thanks! I removed the open item.
Jonathan
Some things from this thread were left for post-11; see attached patch.
Specifically, this changes pg_dump and ruleutils.c to use the FUNCTION
keyword instead of PROCEDURE in trigger and event trigger definitions,
which was postponed because of the required catversion bump.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
0001-Use-EXECUTE-FUNCTION-syntax-for-triggers-more.patchtext/plain; charset=UTF-8; name=0001-Use-EXECUTE-FUNCTION-syntax-for-triggers-more.patch; x-mac-creator=0; x-mac-type=0Download
From 787c5029b82c826e69e5522a12c68ddfe253f01a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 4 Feb 2019 22:38:54 +0100
Subject: [PATCH] Use EXECUTE FUNCTION syntax for triggers more
Change pg_dump and ruleutils.c to use the FUNCTION keyword instead of
PROCEDURE in trigger and event trigger definitions.
This completes the pieces of the transition started in
0a63f996e018ac508c858e87fa39cc254a5db49f that were kept out of
PostgreSQL 11 because of the required catversion change.
---
src/backend/catalog/information_schema.sql | 4 +-
src/backend/utils/adt/ruleutils.c | 2 +-
src/bin/pg_dump/pg_dump.c | 4 +-
src/bin/pg_dump/t/002_pg_dump.pl | 8 ++--
src/include/catalog/catversion.h | 2 +-
src/test/regress/expected/triggers.out | 56 +++++++++++-----------
6 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index b27ff5fa35..94e482596f 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -2094,12 +2094,12 @@ CREATE VIEW triggers AS
AS cardinal_number) AS action_order,
CAST(
CASE WHEN pg_has_role(c.relowner, 'USAGE')
- THEN (regexp_match(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE PROCEDURE'))[1]
+ THEN (regexp_match(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE FUNCTION'))[1]
ELSE null END
AS character_data) AS action_condition,
CAST(
substring(pg_get_triggerdef(t.oid) from
- position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
+ position('EXECUTE FUNCTION' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
AS character_data) AS action_statement,
CAST(
-- hard-wired reference to TRIGGER_TYPE_ROW
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 17a28c2651..e1fbe494d5 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1044,7 +1044,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
appendStringInfoString(&buf, ") ");
}
- appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
+ appendStringInfo(&buf, "EXECUTE FUNCTION %s(",
generate_function_name(trigrec->tgfoid, 0,
NIL, argtypes,
false, NULL, EXPR_KIND_NONE));
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 3a89ad846a..b6030f56ae 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -17086,7 +17086,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
appendPQExpBufferStr(query, " FOR EACH STATEMENT\n ");
/* regproc output is already sufficiently quoted */
- appendPQExpBuffer(query, "EXECUTE PROCEDURE %s(",
+ appendPQExpBuffer(query, "EXECUTE FUNCTION %s(",
tginfo->tgfname);
tgargs = (char *) PQunescapeBytea((unsigned char *) tginfo->tgargs,
@@ -17200,7 +17200,7 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
appendPQExpBufferChar(query, ')');
}
- appendPQExpBufferStr(query, "\n EXECUTE PROCEDURE ");
+ appendPQExpBufferStr(query, "\n EXECUTE FUNCTION ");
appendPQExpBufferStr(query, evtinfo->evtfname);
appendPQExpBufferStr(query, "();\n");
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 245fcbf5ce..4ff0c5645b 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -1540,11 +1540,11 @@
create_order => 33,
create_sql => 'CREATE EVENT TRIGGER test_event_trigger
ON ddl_command_start
- EXECUTE PROCEDURE dump_test.event_trigger_func();',
+ EXECUTE FUNCTION dump_test.event_trigger_func();',
regexp => qr/^
\QCREATE EVENT TRIGGER test_event_trigger \E
\QON ddl_command_start\E
- \n\s+\QEXECUTE PROCEDURE dump_test.event_trigger_func();\E
+ \n\s+\QEXECUTE FUNCTION dump_test.event_trigger_func();\E
/xm,
like => { %full_runs, section_post_data => 1, },
},
@@ -1554,11 +1554,11 @@
create_sql => 'CREATE TRIGGER test_trigger
BEFORE INSERT ON dump_test.test_table
FOR EACH ROW WHEN (NEW.col1 > 10)
- EXECUTE PROCEDURE dump_test.trigger_func();',
+ EXECUTE FUNCTION dump_test.trigger_func();',
regexp => qr/^
\QCREATE TRIGGER test_trigger BEFORE INSERT ON dump_test.test_table \E
\QFOR EACH ROW WHEN ((new.col1 > 10)) \E
- \QEXECUTE PROCEDURE dump_test.trigger_func();\E
+ \QEXECUTE FUNCTION dump_test.trigger_func();\E
/xm,
like => {
%full_runs,
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index ea9a5ade23..b34f40ce0b 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201902011
+#define CATALOG_VERSION_NO 201902041
#endif
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index f561de9222..2b908ceec4 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -417,21 +417,21 @@ SELECT * FROM main_table ORDER BY a, b;
(8 rows)
SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a';
- pg_get_triggerdef
---------------------------------------------------------------------------------------------------------------------------------------------
- CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.a <> new.a) EXECUTE PROCEDURE trigger_func('modified_a')
+ pg_get_triggerdef
+-------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.a <> new.a) EXECUTE FUNCTION trigger_func('modified_a')
(1 row)
SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a';
- pg_get_triggerdef
------------------------------------------------------------------------------------------------------------------------------------------------------
- CREATE TRIGGER modified_a BEFORE UPDATE OF a ON public.main_table FOR EACH ROW WHEN ((old.a <> new.a)) EXECUTE PROCEDURE trigger_func('modified_a')
+ pg_get_triggerdef
+----------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE TRIGGER modified_a BEFORE UPDATE OF a ON public.main_table FOR EACH ROW WHEN ((old.a <> new.a)) EXECUTE FUNCTION trigger_func('modified_a')
(1 row)
SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any';
- pg_get_triggerdef
---------------------------------------------------------------------------------------------------------------------------------------------------------------
- CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.* IS DISTINCT FROM new.*) EXECUTE PROCEDURE trigger_func('modified_any')
+ pg_get_triggerdef
+-------------------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.* IS DISTINCT FROM new.*) EXECUTE FUNCTION trigger_func('modified_any')
(1 row)
-- Test RENAME TRIGGER
@@ -477,9 +477,9 @@ FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_upd_a_stmt');
CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_upd_b_stmt');
SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig';
- pg_get_triggerdef
---------------------------------------------------------------------------------------------------------------------------------------------------
- CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON public.main_table FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_a_b_row')
+ pg_get_triggerdef
+-------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON public.main_table FOR EACH ROW EXECUTE FUNCTION trigger_func('after_upd_a_b_row')
(1 row)
UPDATE main_table SET a = 50;
@@ -1107,15 +1107,15 @@ DELETE 1
a | integer | | |
b | integer | | |
Triggers:
- after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt')
- after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt')
- after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt')
- before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt')
- before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt')
- before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt')
- instead_of_delete_trig INSTEAD OF DELETE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del')
- instead_of_insert_trig INSTEAD OF INSERT ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins')
- instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd')
+ after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_del_stmt')
+ after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_ins_stmt')
+ after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_upd_stmt')
+ before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_del_stmt')
+ before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_ins_stmt')
+ before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_upd_stmt')
+ instead_of_delete_trig INSTEAD OF DELETE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_del')
+ instead_of_insert_trig INSTEAD OF INSERT ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_ins')
+ instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_upd')
-- Test dropping view triggers
DROP TRIGGER instead_of_insert_trig ON main_view;
@@ -1131,13 +1131,13 @@ View definition:
main_table.b
FROM main_table;
Triggers:
- after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt')
- after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt')
- after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt')
- before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt')
- before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt')
- before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt')
- instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd')
+ after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_del_stmt')
+ after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_ins_stmt')
+ after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_upd_stmt')
+ before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_del_stmt')
+ before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_ins_stmt')
+ before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_upd_stmt')
+ instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_upd')
DROP VIEW main_view;
--
--
2.20.1
On 04/02/2019 23:02, Peter Eisentraut wrote:
Some things from this thread were left for post-11; see attached patch.
Specifically, this changes pg_dump and ruleutils.c to use the FUNCTION
keyword instead of PROCEDURE in trigger and event trigger definitions,
which was postponed because of the required catversion bump.
done
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services