Skip to content

Commit 96bd67f

Browse files
committed
Bring CREATE RULE reference page into some semblance of agreement with
what's actually implemented.
1 parent a694461 commit 96bd67f

File tree

1 file changed

+81
-154
lines changed

1 file changed

+81
-154
lines changed

doc/src/sgml/ref/create_rule.sgml

Lines changed: 81 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.20 2000/12/12 16:47:52 momjian Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.21 2001/01/06 04:14:35 tgl Exp $
33
Postgres documentation
44
-->
55

@@ -20,17 +20,27 @@ Postgres documentation
2020
</refnamediv>
2121
<refsynopsisdiv>
2222
<refsynopsisdivinfo>
23-
<date>1999-07-20</date>
23+
<date>2001-01-05</date>
2424
</refsynopsisdivinfo>
2525
<synopsis>
2626
CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable>
2727
TO <replaceable class="parameter">object</replaceable> [ WHERE <replaceable class="parameter">condition</replaceable> ]
28-
DO [ INSTEAD ] [ <replaceable class="parameter">action</replaceable> | NOTHING ]
28+
DO [ INSTEAD ] <replaceable class="parameter">action</replaceable>
29+
30+
where <replaceable class="PARAMETER">action</replaceable> can be:
31+
32+
NOTHING
33+
|
34+
<replaceable class="parameter">query</replaceable>
35+
|
36+
( <replaceable class="parameter">query</replaceable> ; <replaceable class="parameter">query</replaceable> ... )
37+
|
38+
[ <replaceable class="parameter">query</replaceable> ; <replaceable class="parameter">query</replaceable> ... ]
2939
</synopsis>
3040

3141
<refsect2 id="R2-SQL-CREATERULE-1">
3242
<refsect2info>
33-
<date>1998-09-11</date>
43+
<date>2001-01-05</date>
3444
</refsect2info>
3545
<title>
3646
Inputs
@@ -50,9 +60,9 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable
5060
<term><replaceable class="parameter">event</replaceable></term>
5161
<listitem>
5262
<para>
53-
Event is one of <literal>select</literal>,
54-
<literal>update</literal>, <literal>delete</literal>
55-
or <literal>insert</literal>.
63+
Event is one of <literal>SELECT</literal>,
64+
<literal>UPDATE</literal>, <literal>DELETE</literal>
65+
or <literal>INSERT</literal>.
5666
</para>
5767
</listitem>
5868
</varlistentry>
@@ -62,32 +72,48 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable
6272
<para>
6373
Object is either <replaceable class="parameter">table</replaceable>
6474
or <replaceable class="parameter">table</replaceable>.<replaceable
65-
class="parameter">column</replaceable>.
75+
class="parameter">column</replaceable>. (Currently, only the
76+
<replaceable class="parameter">table</replaceable> form is
77+
actually implemented.)
6678
</para>
6779
</listitem>
6880
</varlistentry>
6981
<varlistentry>
7082
<term><replaceable class="parameter">condition</replaceable></term>
7183
<listitem>
7284
<para>
73-
Any SQL WHERE clause, <literal>new</literal> or
74-
<literal>old</literal>, can appear instead of an instance
75-
variable whenever an instance variable is permissible in SQL.
85+
Any SQL boolean-condition expression. The condition expression may not
86+
refer to any tables except <literal>new</literal> and
87+
<literal>old</literal>.
7688
</para>
7789
</listitem>
7890
</varlistentry>
7991
<varlistentry>
80-
<term><replaceable class="parameter">action</replaceable></term>
92+
<term><replaceable class="parameter">query</replaceable></term>
8193
<listitem>
8294
<para>
83-
Any SQL statement, <literal>new</literal> or
84-
<literal>old</literal>, can appear instead of an instance
85-
variable whenever an instance variable is permissible in SQL.
95+
The query or queries making up the
96+
<replaceable class="PARAMETER">action</replaceable>
97+
can be any SQL <literal>SELECT</literal>, <literal>INSERT</literal>,
98+
<literal>UPDATE</literal>, <literal>DELETE</literal>, or
99+
<literal>NOTIFY</literal> statement.
86100
</para>
87101
</listitem>
88102
</varlistentry>
89103
</variablelist>
90104
</para>
105+
106+
<para>
107+
Within the <replaceable class="parameter">condition</replaceable>
108+
and <replaceable class="PARAMETER">action</replaceable>, the special
109+
table names <literal>new</literal> and <literal>old</literal> may be
110+
used to refer to values in the referenced table (the
111+
<replaceable class="parameter">object</replaceable>).
112+
<literal>new</literal> is valid in ON INSERT and ON UPDATE rules
113+
to refer to the new row being inserted or updated.
114+
<literal>old</literal> is valid in ON SELECT, ON UPDATE, and ON DELETE
115+
rules to refer to the existing row being selected, updated, or deleted.
116+
</para>
91117
</refsect2>
92118

93119
<refsect2 id="R2-SQL-CREATERULE-2">
@@ -127,26 +153,42 @@ CREATE
127153
The <productname>Postgres</productname>
128154
<firstterm>rule system</firstterm> allows one to define an
129155
alternate action to be performed on inserts, updates, or deletions
130-
from database tables or classes. Currently, rules are used to
131-
implement table views.
156+
from database tables. Rules are used to
157+
implement table views as well.
132158
</para>
133159

134160
<para>
135-
The semantics of a rule is that at the time an individual instance is
161+
The semantics of a rule is that at the time an individual instance (row)
162+
is
136163
accessed, inserted, updated, or deleted, there is an old instance (for
137164
selects, updates and deletes) and a new instance (for inserts and
138-
updates).
139-
If the <replaceable class="parameter">event</replaceable>
140-
specified in the ON clause and the
165+
updates). All the rules for the given event type and the given target
166+
object (table) are examined, in an unspecified order. If the
141167
<replaceable class="parameter">condition</replaceable> specified in the
142-
WHERE clause are true for the old instance, the
168+
WHERE clause (if any) is true, the
143169
<replaceable class="parameter">action</replaceable> part of the rule is
144-
executed. First, however, values from fields in the old instance
145-
and/or the new instance are substituted for
170+
executed. The <replaceable class="parameter">action</replaceable> is
171+
done instead of the original query if INSTEAD is specified; otherwise
172+
it is done before the original query is performed.
173+
Within both the <replaceable class="parameter">condition</replaceable>
174+
and <replaceable class="parameter">action</replaceable>, values from
175+
fields in the old instance and/or the new instance are substituted for
146176
<literal>old.</literal><replaceable class="parameter">attribute-name</replaceable>
147177
and <literal>new.</literal><replaceable class="parameter">attribute-name</replaceable>.
148178
</para>
149179

180+
<para>
181+
The <replaceable class="parameter">action</replaceable> part of the rule
182+
can consist of one or more queries. To write multiple queries, surround
183+
them with either parentheses or square brackets. Such queries will be
184+
performed in the specified order (whereas there are no guarantees about
185+
the execution order of multiple rules for an object). The
186+
<replaceable class="parameter">action</replaceable> can also be NOTHING
187+
indicating no action. Thus, a DO INSTEAD NOTHING rule suppresses the
188+
original query from executing (when its condition is true); a DO NOTHING
189+
rule is useless.
190+
</para>
191+
150192
<para>
151193
The <replaceable class="parameter">action</replaceable> part of the rule
152194
executes with the same command and transaction identifier as the user
@@ -155,47 +197,29 @@ CREATE
155197

156198
<refsect2 id="R2-SQL-CREATERULE-3">
157199
<refsect2info>
158-
<date>1998-09-11</date>
200+
<date>2001-01-05</date>
159201
</refsect2info>
160202
<title>
161203
Notes
162204
</title>
163205
<para>
164-
A caution about SQL rules is in order. If the same class name
165-
or instance variable appears in the
166-
<replaceable class="parameter">event</replaceable>,
167-
<replaceable class="parameter">condition</replaceable> and
168-
<replaceable class="parameter">action</replaceable> parts of a rule,
169-
they are all considered different tuple variables. More accurately,
170-
<literal>new</literal> and <literal>old</literal> are the only tuple
171-
variables that are shared between these clauses. For example, the following
172-
two rules have the same semantics:
173-
<programlisting>
174-
ON UPDATE TO emp.salary WHERE emp.name = "Joe"
175-
DO
176-
UPDATE emp SET ... WHERE ...
177-
</programlisting>
178-
179-
<programlisting>
180-
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe"
181-
DO
182-
UPDATE emp-3 SET ... WHERE ...
183-
</programlisting>
206+
Presently, ON SELECT rules must be unconditional INSTEAD rules and must
207+
have actions that consist of a single SELECT query. Thus, an ON SELECT
208+
rule effectively turns the object table into a view, whose visible
209+
contents are the rows returned by the rule's SELECT query rather than
210+
whatever had been stored in the table (if anything). It is considered
211+
better style to write a CREATE VIEW command than to create a table and
212+
define an ON SELECT rule for it.
213+
</para>
184214

185-
Each rule can have the optional tag INSTEAD.
186-
Without
187-
this tag, <replaceable class="parameter">action</replaceable> will be
188-
performed in addition to the user command when the
189-
<replaceable class="parameter">event</replaceable> in the
190-
<replaceable class="parameter">condition</replaceable> part of the rule
191-
occurs. Alternately, the
192-
<replaceable class="parameter">action</replaceable> part will be done
193-
instead of the user command. In this latter case, the
194-
<replaceable class="parameter">action</replaceable> can be the keyword
195-
<literal>NOTHING</literal>.
215+
<para>
216+
You must have rule definition access to a class in order
217+
to define a rule on it. Use <command>GRANT</command>
218+
and <command>REVOKE</command> to change permissions.
196219
</para>
220+
197221
<para>
198-
It is very important to note to avoid circular rules.
222+
It is very important to take care to avoid circular rules.
199223
For example, though each
200224
of the following two rule definitions are accepted by
201225
<productname>Postgres</productname>, the
@@ -226,105 +250,8 @@ SELECT * FROM emp;
226250
</programlisting></para>
227251
</example>
228252
</para>
229-
230-
<para>
231-
You must have rule definition access to a class in order
232-
to define a rule on it. Use <command>GRANT</command>
233-
and <command>REVOKE</command> to change permissions.
234-
</para>
235-
236-
<para>
237-
The object in a <acronym>SQL</acronym> rule cannot be an array reference and
238-
cannot have parameters.
239-
</para>
240-
241-
<para>
242-
Aside from the "oid" field, system attributes cannot be
243-
referenced anywhere in a rule. Among other things, this
244-
means that functions of instances (e.g., <literal>foo(emp)</literal> where
245-
<literal>emp</literal> is a class) cannot be called anywhere in a rule.
246-
</para>
247-
248-
<para>
249-
The rule system stores the rule text and query plans as
250-
text attributes. This implies that creation of rules may
251-
fail if the rule plus its various internal representations
252-
exceed some value that is on the order of one page (8KB).
253-
</para>
254253
</refsect2>
255254
</refsect1>
256-
257-
<refsect1 id="R1-SQL-CREATERULE-2">
258-
<title>
259-
Usage
260-
</title>
261-
<para>
262-
Make Sam get the same salary adjustment as Joe:
263-
264-
<programlisting>
265-
CREATE RULE example_1 AS
266-
ON UPDATE emp.salary WHERE old.name = "Joe"
267-
DO
268-
UPDATE emp
269-
SET salary = new.salary
270-
WHERE emp.name = "Sam";
271-
</programlisting>
272-
273-
At the time Joe receives a salary adjustment, the event
274-
will become true and Joe's old instance and proposed
275-
new instance are available to the execution routines.
276-
Hence, his new salary is substituted into the action part
277-
of the rule which is subsequently executed. This propagates
278-
Joe's salary on to Sam.
279-
</para>
280-
<para>
281-
Make Bill get Joe's salary when it is accessed:
282-
<programlisting>
283-
CREATE RULE example_2 AS
284-
ON SELECT TO EMP.salary
285-
WHERE old.name = "Bill"
286-
DO INSTEAD
287-
SELECT emp.salary
288-
FROM emp
289-
WHERE emp.name = "Joe";
290-
</programlisting>
291-
</para>
292-
<para>
293-
Deny Joe access to the salary of employees in the shoe
294-
department (<function>current_user</function> returns the name of
295-
the current user):
296-
<programlisting>
297-
CREATE RULE example_3 AS
298-
ON
299-
SELECT TO emp.salary
300-
WHERE old.dept = "shoe" AND current_user = "Joe"
301-
DO INSTEAD NOTHING;
302-
</programlisting>
303-
</para>
304-
<para>
305-
Create a view of the employees working in the toy department:
306-
<programlisting>
307-
CREATE toyemp(name = char16, salary = int4);
308-
309-
CREATE RULE example_4 AS
310-
ON SELECT TO toyemp
311-
DO INSTEAD
312-
SELECT emp.name, emp.salary
313-
FROM emp
314-
WHERE emp.dept = "toy";
315-
</programlisting>
316-
</para>
317-
<para>
318-
All new employees must make 5,000 or less:
319-
<programlisting>
320-
CREATE RULE example_5 AS
321-
ON INERT TO emp WHERE new.salary > 5000
322-
DO
323-
UPDATE emp SET salary = 5000
324-
WHERE emp.oid = new.oid;
325-
</programlisting>
326-
</para>
327-
</refsect1>
328255

329256
<refsect1 id="R1-SQL-CREATERULE-4">
330257
<title>

0 commit comments

Comments
 (0)