1
1
<!--
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 $
3
3
Postgres documentation
4
4
-->
5
5
@@ -20,17 +20,27 @@ Postgres documentation
20
20
</refnamediv>
21
21
<refsynopsisdiv>
22
22
<refsynopsisdivinfo>
23
- <date>1999-07-20 </date>
23
+ <date>2001-01-05 </date>
24
24
</refsynopsisdivinfo>
25
25
<synopsis>
26
26
CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable>
27
27
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> ... ]
29
39
</synopsis>
30
40
31
41
<refsect2 id="R2-SQL-CREATERULE-1">
32
42
<refsect2info>
33
- <date>1998-09-11 </date>
43
+ <date>2001-01-05 </date>
34
44
</refsect2info>
35
45
<title>
36
46
Inputs
@@ -50,9 +60,9 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable
50
60
<term><replaceable class="parameter">event</replaceable></term>
51
61
<listitem>
52
62
<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>.
56
66
</para>
57
67
</listitem>
58
68
</varlistentry>
@@ -62,32 +72,48 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable
62
72
<para>
63
73
Object is either <replaceable class="parameter">table</replaceable>
64
74
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.)
66
78
</para>
67
79
</listitem>
68
80
</varlistentry>
69
81
<varlistentry>
70
82
<term><replaceable class="parameter">condition</replaceable></term>
71
83
<listitem>
72
84
<para>
73
- Any SQLWHERE 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 SQLboolean-condition expression. The condition expression may not
86
+ refer to any tables except <literal>new </literal> and
87
+ <literal>old</literal> .
76
88
</para>
77
89
</listitem>
78
90
</varlistentry>
79
91
<varlistentry>
80
- <term><replaceable class="parameter">action </replaceable></term>
92
+ <term><replaceable class="parameter">query </replaceable></term>
81
93
<listitem>
82
94
<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.
86
100
</para>
87
101
</listitem>
88
102
</varlistentry>
89
103
</variablelist>
90
104
</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>
91
117
</refsect2>
92
118
93
119
<refsect2 id="R2-SQL-CREATERULE-2">
@@ -127,26 +153,42 @@ CREATE
127
153
The <productname>Postgres</productname>
128
154
<firstterm>rule system</firstterm> allows one to define an
129
155
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 .
132
158
</para>
133
159
134
160
<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
136
163
accessed, inserted, updated, or deleted, there is an old instance (for
137
164
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
141
167
<replaceable class="parameter">condition</replaceable> specified in the
142
- WHERE clauseare true for the old instance , the
168
+ WHERE clause(if any) is true , the
143
169
<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
146
176
<literal>old.</literal><replaceable class="parameter">attribute-name</replaceable>
147
177
and <literal>new.</literal><replaceable class="parameter">attribute-name</replaceable>.
148
178
</para>
149
179
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
+
150
192
<para>
151
193
The <replaceable class="parameter">action</replaceable> part of the rule
152
194
executes with the same command and transaction identifier as the user
@@ -155,47 +197,29 @@ CREATE
155
197
156
198
<refsect2 id="R2-SQL-CREATERULE-3">
157
199
<refsect2info>
158
- <date>1998-09-11 </date>
200
+ <date>2001-01-05 </date>
159
201
</refsect2info>
160
202
<title>
161
203
Notes
162
204
</title>
163
205
<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>
184
214
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.
196
219
</para>
220
+
197
221
<para>
198
- It is very important tonote to avoid circular rules.
222
+ It is very important totake care to avoid circular rules.
199
223
For example, though each
200
224
of the following two rule definitions are accepted by
201
225
<productname>Postgres</productname>, the
@@ -226,105 +250,8 @@ SELECT * FROM emp;
226
250
</programlisting></para>
227
251
</example>
228
252
</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>
254
253
</refsect2>
255
254
</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>
328
255
329
256
<refsect1 id="R1-SQL-CREATERULE-4">
330
257
<title>