|
|
|
@ -1,5 +1,5 @@ |
|
|
|
|
<!-- |
|
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.20 2000/12/12 16:47:52 momjian Exp $ |
|
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.21 2001/01/06 04:14:35 tgl Exp $ |
|
|
|
|
Postgres documentation |
|
|
|
|
--> |
|
|
|
|
|
|
|
|
@ -20,17 +20,27 @@ Postgres documentation |
|
|
|
|
</refnamediv> |
|
|
|
|
<refsynopsisdiv> |
|
|
|
|
<refsynopsisdivinfo> |
|
|
|
|
<date>1999-07-20</date> |
|
|
|
|
<date>2001-01-05</date> |
|
|
|
|
</refsynopsisdivinfo> |
|
|
|
|
<synopsis> |
|
|
|
|
CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable> |
|
|
|
|
TO <replaceable class="parameter">object</replaceable> [ WHERE <replaceable class="parameter">condition</replaceable> ] |
|
|
|
|
DO [ INSTEAD ] [ <replaceable class="parameter">action</replaceable> | NOTHING ] |
|
|
|
|
DO [ INSTEAD ] <replaceable class="parameter">action</replaceable> |
|
|
|
|
|
|
|
|
|
where <replaceable class="PARAMETER">action</replaceable> can be: |
|
|
|
|
|
|
|
|
|
NOTHING |
|
|
|
|
| |
|
|
|
|
<replaceable class="parameter">query</replaceable> |
|
|
|
|
| |
|
|
|
|
( <replaceable class="parameter">query</replaceable> ; <replaceable class="parameter">query</replaceable> ... ) |
|
|
|
|
| |
|
|
|
|
[ <replaceable class="parameter">query</replaceable> ; <replaceable class="parameter">query</replaceable> ... ] |
|
|
|
|
</synopsis> |
|
|
|
|
|
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-1"> |
|
|
|
|
<refsect2info> |
|
|
|
|
<date>1998-09-11</date> |
|
|
|
|
<date>2001-01-05</date> |
|
|
|
|
</refsect2info> |
|
|
|
|
<title> |
|
|
|
|
Inputs |
|
|
|
@ -50,9 +60,9 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable |
|
|
|
|
<term><replaceable class="parameter">event</replaceable></term> |
|
|
|
|
<listitem> |
|
|
|
|
<para> |
|
|
|
|
Event is one of <literal>select</literal>, |
|
|
|
|
<literal>update</literal>, <literal>delete</literal> |
|
|
|
|
or <literal>insert</literal>. |
|
|
|
|
Event is one of <literal>SELECT</literal>, |
|
|
|
|
<literal>UPDATE</literal>, <literal>DELETE</literal> |
|
|
|
|
or <literal>INSERT</literal>. |
|
|
|
|
</para> |
|
|
|
|
</listitem> |
|
|
|
|
</varlistentry> |
|
|
|
@ -62,7 +72,9 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable |
|
|
|
|
<para> |
|
|
|
|
Object is either <replaceable class="parameter">table</replaceable> |
|
|
|
|
or <replaceable class="parameter">table</replaceable>.<replaceable |
|
|
|
|
class="parameter">column</replaceable>. |
|
|
|
|
class="parameter">column</replaceable>. (Currently, only the |
|
|
|
|
<replaceable class="parameter">table</replaceable> form is |
|
|
|
|
actually implemented.) |
|
|
|
|
</para> |
|
|
|
|
</listitem> |
|
|
|
|
</varlistentry> |
|
|
|
@ -70,24 +82,38 @@ CREATE RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable |
|
|
|
|
<term><replaceable class="parameter">condition</replaceable></term> |
|
|
|
|
<listitem> |
|
|
|
|
<para> |
|
|
|
|
Any SQL WHERE clause, <literal>new</literal> or |
|
|
|
|
<literal>old</literal>, can appear instead of an instance |
|
|
|
|
variable whenever an instance variable is permissible in SQL. |
|
|
|
|
Any SQL boolean-condition expression. The condition expression may not |
|
|
|
|
refer to any tables except <literal>new</literal> and |
|
|
|
|
<literal>old</literal>. |
|
|
|
|
</para> |
|
|
|
|
</listitem> |
|
|
|
|
</varlistentry> |
|
|
|
|
<varlistentry> |
|
|
|
|
<term><replaceable class="parameter">action</replaceable></term> |
|
|
|
|
<term><replaceable class="parameter">query</replaceable></term> |
|
|
|
|
<listitem> |
|
|
|
|
<para> |
|
|
|
|
Any SQL statement, <literal>new</literal> or |
|
|
|
|
<literal>old</literal>, can appear instead of an instance |
|
|
|
|
variable whenever an instance variable is permissible in SQL. |
|
|
|
|
The query or queries making up the |
|
|
|
|
<replaceable class="PARAMETER">action</replaceable> |
|
|
|
|
can be any SQL <literal>SELECT</literal>, <literal>INSERT</literal>, |
|
|
|
|
<literal>UPDATE</literal>, <literal>DELETE</literal>, or |
|
|
|
|
<literal>NOTIFY</literal> statement. |
|
|
|
|
</para> |
|
|
|
|
</listitem> |
|
|
|
|
</varlistentry> |
|
|
|
|
</variablelist> |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
Within the <replaceable class="parameter">condition</replaceable> |
|
|
|
|
and <replaceable class="PARAMETER">action</replaceable>, the special |
|
|
|
|
table names <literal>new</literal> and <literal>old</literal> may be |
|
|
|
|
used to refer to values in the referenced table (the |
|
|
|
|
<replaceable class="parameter">object</replaceable>). |
|
|
|
|
<literal>new</literal> is valid in ON INSERT and ON UPDATE rules |
|
|
|
|
to refer to the new row being inserted or updated. |
|
|
|
|
<literal>old</literal> is valid in ON SELECT, ON UPDATE, and ON DELETE |
|
|
|
|
rules to refer to the existing row being selected, updated, or deleted. |
|
|
|
|
</para> |
|
|
|
|
</refsect2> |
|
|
|
|
|
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-2"> |
|
|
|
@ -127,26 +153,42 @@ CREATE |
|
|
|
|
The <productname>Postgres</productname> |
|
|
|
|
<firstterm>rule system</firstterm> allows one to define an |
|
|
|
|
alternate action to be performed on inserts, updates, or deletions |
|
|
|
|
from database tables or classes. Currently, rules are used to |
|
|
|
|
implement table views. |
|
|
|
|
from database tables. Rules are used to |
|
|
|
|
implement table views as well. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
The semantics of a rule is that at the time an individual instance is |
|
|
|
|
The semantics of a rule is that at the time an individual instance (row) |
|
|
|
|
is |
|
|
|
|
accessed, inserted, updated, or deleted, there is an old instance (for |
|
|
|
|
selects, updates and deletes) and a new instance (for inserts and |
|
|
|
|
updates). |
|
|
|
|
If the <replaceable class="parameter">event</replaceable> |
|
|
|
|
specified in the ON clause and the |
|
|
|
|
updates). All the rules for the given event type and the given target |
|
|
|
|
object (table) are examined, in an unspecified order. If the |
|
|
|
|
<replaceable class="parameter">condition</replaceable> specified in the |
|
|
|
|
WHERE clause are true for the old instance, the |
|
|
|
|
WHERE clause (if any) is true, the |
|
|
|
|
<replaceable class="parameter">action</replaceable> part of the rule is |
|
|
|
|
executed. First, however, values from fields in the old instance |
|
|
|
|
and/or the new instance are substituted for |
|
|
|
|
executed. The <replaceable class="parameter">action</replaceable> is |
|
|
|
|
done instead of the original query if INSTEAD is specified; otherwise |
|
|
|
|
it is done before the original query is performed. |
|
|
|
|
Within both the <replaceable class="parameter">condition</replaceable> |
|
|
|
|
and <replaceable class="parameter">action</replaceable>, values from |
|
|
|
|
fields in the old instance and/or the new instance are substituted for |
|
|
|
|
<literal>old.</literal><replaceable class="parameter">attribute-name</replaceable> |
|
|
|
|
and <literal>new.</literal><replaceable class="parameter">attribute-name</replaceable>. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
The <replaceable class="parameter">action</replaceable> part of the rule |
|
|
|
|
can consist of one or more queries. To write multiple queries, surround |
|
|
|
|
them with either parentheses or square brackets. Such queries will be |
|
|
|
|
performed in the specified order (whereas there are no guarantees about |
|
|
|
|
the execution order of multiple rules for an object). The |
|
|
|
|
<replaceable class="parameter">action</replaceable> can also be NOTHING |
|
|
|
|
indicating no action. Thus, a DO INSTEAD NOTHING rule suppresses the |
|
|
|
|
original query from executing (when its condition is true); a DO NOTHING |
|
|
|
|
rule is useless. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
The <replaceable class="parameter">action</replaceable> part of the rule |
|
|
|
|
executes with the same command and transaction identifier as the user |
|
|
|
@ -155,47 +197,29 @@ CREATE |
|
|
|
|
|
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-3"> |
|
|
|
|
<refsect2info> |
|
|
|
|
<date>1998-09-11</date> |
|
|
|
|
<date>2001-01-05</date> |
|
|
|
|
</refsect2info> |
|
|
|
|
<title> |
|
|
|
|
Notes |
|
|
|
|
</title> |
|
|
|
|
<para> |
|
|
|
|
A caution about SQL rules is in order. If the same class name |
|
|
|
|
or instance variable appears in the |
|
|
|
|
<replaceable class="parameter">event</replaceable>, |
|
|
|
|
<replaceable class="parameter">condition</replaceable> and |
|
|
|
|
<replaceable class="parameter">action</replaceable> parts of a rule, |
|
|
|
|
they are all considered different tuple variables. More accurately, |
|
|
|
|
<literal>new</literal> and <literal>old</literal> are the only tuple |
|
|
|
|
variables that are shared between these clauses. For example, the following |
|
|
|
|
two rules have the same semantics: |
|
|
|
|
<programlisting> |
|
|
|
|
ON UPDATE TO emp.salary WHERE emp.name = "Joe" |
|
|
|
|
DO |
|
|
|
|
UPDATE emp SET ... WHERE ... |
|
|
|
|
</programlisting> |
|
|
|
|
|
|
|
|
|
<programlisting> |
|
|
|
|
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe" |
|
|
|
|
DO |
|
|
|
|
UPDATE emp-3 SET ... WHERE ... |
|
|
|
|
</programlisting> |
|
|
|
|
Presently, ON SELECT rules must be unconditional INSTEAD rules and must |
|
|
|
|
have actions that consist of a single SELECT query. Thus, an ON SELECT |
|
|
|
|
rule effectively turns the object table into a view, whose visible |
|
|
|
|
contents are the rows returned by the rule's SELECT query rather than |
|
|
|
|
whatever had been stored in the table (if anything). It is considered |
|
|
|
|
better style to write a CREATE VIEW command than to create a table and |
|
|
|
|
define an ON SELECT rule for it. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
Each rule can have the optional tag INSTEAD. |
|
|
|
|
Without |
|
|
|
|
this tag, <replaceable class="parameter">action</replaceable> will be |
|
|
|
|
performed in addition to the user command when the |
|
|
|
|
<replaceable class="parameter">event</replaceable> in the |
|
|
|
|
<replaceable class="parameter">condition</replaceable> part of the rule |
|
|
|
|
occurs. Alternately, the |
|
|
|
|
<replaceable class="parameter">action</replaceable> part will be done |
|
|
|
|
instead of the user command. In this latter case, the |
|
|
|
|
<replaceable class="parameter">action</replaceable> can be the keyword |
|
|
|
|
<literal>NOTHING</literal>. |
|
|
|
|
<para> |
|
|
|
|
You must have rule definition access to a class in order |
|
|
|
|
to define a rule on it. Use <command>GRANT</command> |
|
|
|
|
and <command>REVOKE</command> to change permissions. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
It is very important to note to avoid circular rules. |
|
|
|
|
It is very important to take care to avoid circular rules. |
|
|
|
|
For example, though each |
|
|
|
|
of the following two rule definitions are accepted by |
|
|
|
|
<productname>Postgres</productname>, the |
|
|
|
@ -226,105 +250,8 @@ SELECT * FROM emp; |
|
|
|
|
</programlisting></para> |
|
|
|
|
</example> |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
You must have rule definition access to a class in order |
|
|
|
|
to define a rule on it. Use <command>GRANT</command> |
|
|
|
|
and <command>REVOKE</command> to change permissions. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
The object in a <acronym>SQL</acronym> rule cannot be an array reference and |
|
|
|
|
cannot have parameters. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
Aside from the "oid" field, system attributes cannot be |
|
|
|
|
referenced anywhere in a rule. Among other things, this |
|
|
|
|
means that functions of instances (e.g., <literal>foo(emp)</literal> where |
|
|
|
|
<literal>emp</literal> is a class) cannot be called anywhere in a rule. |
|
|
|
|
</para> |
|
|
|
|
|
|
|
|
|
<para> |
|
|
|
|
The rule system stores the rule text and query plans as |
|
|
|
|
text attributes. This implies that creation of rules may |
|
|
|
|
fail if the rule plus its various internal representations |
|
|
|
|
exceed some value that is on the order of one page (8KB). |
|
|
|
|
</para> |
|
|
|
|
</refsect2> |
|
|
|
|
</refsect1> |
|
|
|
|
|
|
|
|
|
<refsect1 id="R1-SQL-CREATERULE-2"> |
|
|
|
|
<title> |
|
|
|
|
Usage |
|
|
|
|
</title> |
|
|
|
|
<para> |
|
|
|
|
Make Sam get the same salary adjustment as Joe: |
|
|
|
|
|
|
|
|
|
<programlisting> |
|
|
|
|
CREATE RULE example_1 AS |
|
|
|
|
ON UPDATE emp.salary WHERE old.name = "Joe" |
|
|
|
|
DO |
|
|
|
|
UPDATE emp |
|
|
|
|
SET salary = new.salary |
|
|
|
|
WHERE emp.name = "Sam"; |
|
|
|
|
</programlisting> |
|
|
|
|
|
|
|
|
|
At the time Joe receives a salary adjustment, the event |
|
|
|
|
will become true and Joe's old instance and proposed |
|
|
|
|
new instance are available to the execution routines. |
|
|
|
|
Hence, his new salary is substituted into the action part |
|
|
|
|
of the rule which is subsequently executed. This propagates |
|
|
|
|
Joe's salary on to Sam. |
|
|
|
|
</para> |
|
|
|
|
<para> |
|
|
|
|
Make Bill get Joe's salary when it is accessed: |
|
|
|
|
<programlisting> |
|
|
|
|
CREATE RULE example_2 AS |
|
|
|
|
ON SELECT TO EMP.salary |
|
|
|
|
WHERE old.name = "Bill" |
|
|
|
|
DO INSTEAD |
|
|
|
|
SELECT emp.salary |
|
|
|
|
FROM emp |
|
|
|
|
WHERE emp.name = "Joe"; |
|
|
|
|
</programlisting> |
|
|
|
|
</para> |
|
|
|
|
<para> |
|
|
|
|
Deny Joe access to the salary of employees in the shoe |
|
|
|
|
department (<function>current_user</function> returns the name of |
|
|
|
|
the current user): |
|
|
|
|
<programlisting> |
|
|
|
|
CREATE RULE example_3 AS |
|
|
|
|
ON |
|
|
|
|
SELECT TO emp.salary |
|
|
|
|
WHERE old.dept = "shoe" AND current_user = "Joe" |
|
|
|
|
DO INSTEAD NOTHING; |
|
|
|
|
</programlisting> |
|
|
|
|
</para> |
|
|
|
|
<para> |
|
|
|
|
Create a view of the employees working in the toy department: |
|
|
|
|
<programlisting> |
|
|
|
|
CREATE toyemp(name = char16, salary = int4); |
|
|
|
|
|
|
|
|
|
CREATE RULE example_4 AS |
|
|
|
|
ON SELECT TO toyemp |
|
|
|
|
DO INSTEAD |
|
|
|
|
SELECT emp.name, emp.salary |
|
|
|
|
FROM emp |
|
|
|
|
WHERE emp.dept = "toy"; |
|
|
|
|
</programlisting> |
|
|
|
|
</para> |
|
|
|
|
<para> |
|
|
|
|
All new employees must make 5,000 or less: |
|
|
|
|
<programlisting> |
|
|
|
|
CREATE RULE example_5 AS |
|
|
|
|
ON INERT TO emp WHERE new.salary > 5000 |
|
|
|
|
DO |
|
|
|
|
UPDATE emp SET salary = 5000 |
|
|
|
|
WHERE emp.oid = new.oid; |
|
|
|
|
</programlisting> |
|
|
|
|
</para> |
|
|
|
|
</refsect1> |
|
|
|
|
|
|
|
|
|
<refsect1 id="R1-SQL-CREATERULE-4"> |
|
|
|
|
<title> |
|
|
|
|