mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-22 11:43:24 +02:00
359 lines
11 KiB
Plaintext
359 lines
11 KiB
Plaintext
<!--
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.10 1999/07/22 15:09:08 thomas Exp $
|
|
Postgres documentation
|
|
-->
|
|
|
|
<refentry id="SQL-CREATERULE">
|
|
<refmeta>
|
|
<refentrytitle id="sql-createrule-title">
|
|
CREATE RULE
|
|
</refentrytitle>
|
|
<refmiscinfo>SQL - Language Statements</refmiscinfo>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>
|
|
CREATE RULE
|
|
</refname>
|
|
<refpurpose>
|
|
Defines a new rule
|
|
</refpurpose>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<refsynopsisdivinfo>
|
|
<date>1999-07-20</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 ]
|
|
</synopsis>
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-1">
|
|
<refsect2info>
|
|
<date>1998-09-11</date>
|
|
</refsect2info>
|
|
<title>
|
|
Inputs
|
|
</title>
|
|
<para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><replaceable class="parameter">name</replaceable></term>
|
|
<listitem>
|
|
<para>
|
|
The name of a rule to create.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<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>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><replaceable class="parameter">object</replaceable></term>
|
|
<listitem>
|
|
<para>
|
|
Object is either <replaceable class="parameter">table</replaceable>
|
|
or <replaceable class="parameter">table</replaceable>.<replaceable
|
|
class="parameter">column</replaceable>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><replaceable class="parameter">condition</replaceable></term>
|
|
<listitem>
|
|
<para>
|
|
Any SQL WHERE clause. <literal>new</literal> or
|
|
<literal>current</literal> can appear instead of an instance
|
|
variable whenever an instance variable is permissible in SQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><replaceable class="parameter">action</replaceable></term>
|
|
<listitem>
|
|
<para>
|
|
Any SQL statement. <literal>new</literal> or
|
|
<literal>current</literal> can appear instead of an instance
|
|
variable whenever an instance variable is permissible in SQL.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-2">
|
|
<refsect2info>
|
|
<date>1998-09-11</date>
|
|
</refsect2info>
|
|
<title>
|
|
Outputs
|
|
</title>
|
|
<para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><computeroutput>
|
|
CREATE
|
|
</computeroutput></term>
|
|
<listitem>
|
|
<para>
|
|
Message returned if the rule is successfully created.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</refsect2>
|
|
</refsynopsisdiv>
|
|
|
|
<refsect1 id="R1-SQL-CREATERULE-1">
|
|
<refsect1info>
|
|
<date>1998-09-11</date>
|
|
</refsect1info>
|
|
<title>
|
|
Description
|
|
</title>
|
|
|
|
<para>
|
|
The <productname>Postgres</productname>
|
|
<firstterm>rule system</firstterm> allows one to define an
|
|
alternate action to be performed on updates, inserts, or deletions
|
|
from database tables or classes. Currently, rules are used to
|
|
implement table views.
|
|
</para>
|
|
|
|
<para>
|
|
The semantics of a rule is that at the time an individual instance is
|
|
accessed, updated, inserted or deleted, there is a current instance (for
|
|
retrieves, updates and deletes) and a new instance (for updates and
|
|
appends). If the <replaceable class="parameter">event</replaceable>
|
|
specified in the ON clause and the
|
|
<replaceable class="parameter">condition</replaceable> specified in the
|
|
WHERE clause are true for the current instance, the
|
|
<replaceable class="parameter">action</replaceable> part of the rule is
|
|
executed. First, however, values from fields in the current instance
|
|
and/or the new instance are substituted for
|
|
<literal>current.</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
|
|
executes with the same command and transaction identifier as the user
|
|
command that caused activation.
|
|
</para>
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-3">
|
|
<refsect2info>
|
|
<date>1998-09-11</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>, the
|
|
<replaceable class="parameter">condition</replaceable> and the
|
|
<replaceable class="parameter">action</replaceable> parts of a rule,
|
|
they are all considered different tuple variables. More accurately,
|
|
<literal>new</literal> and <literal>current</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 ( ... ) WHERE ...
|
|
</programlisting>
|
|
|
|
<programlisting>
|
|
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe"
|
|
DO UPDATE emp-3 ( ... ) WHERE ...
|
|
</programlisting>
|
|
|
|
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 later case, the
|
|
<replaceable class="parameter">action</replaceable> can be the keyword
|
|
<literal>NOTHING</literal>.
|
|
</para>
|
|
<para>
|
|
When choosing between the rewrite and instance rule systems for a
|
|
particular rule application, remember that in the rewrite system,
|
|
<literal>current</literal> refers to a relation and some qualifiers
|
|
whereas in the instance system it refers to an instance (tuple).
|
|
</para>
|
|
<para>
|
|
It is very important to note that the rewrite rule system
|
|
will neither detect nor process circular rules. For example, though each
|
|
of the following two rule definitions are accepted by
|
|
<productname>Postgres</productname>, the
|
|
retrieve command will cause <productname>Postgres</productname> to crash:
|
|
|
|
<example>
|
|
<title>Example of a circular rewrite rule combination.</title>
|
|
<programlisting>
|
|
CREATE RULE bad_rule_combination_1 AS
|
|
ON SELECT TO emp
|
|
DO INSTEAD SELECT TO toyemp;
|
|
</programlisting>
|
|
|
|
<programlisting>
|
|
CREATE RULE bad_rule_combination_2 AS
|
|
ON SELECT TO toyemp
|
|
DO INSTEAD SELECT TO emp;
|
|
</programlisting>
|
|
<para>
|
|
This attempt to retrieve from EMP will cause
|
|
<productname>Postgres</productname> to crash.
|
|
<programlisting>
|
|
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 current.name = "Joe"
|
|
DO UPDATE emp (salary = new.salary)
|
|
WHERE emp.name = "Sam";
|
|
</programlisting>
|
|
|
|
At the time Joe receives a salary adjustment, the event
|
|
will become true and Joe's current 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 current.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 current.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 NEWSET salary = 5000;
|
|
</programlisting>
|
|
</para>
|
|
</refsect1>
|
|
|
|
<refsect1 id="R1-SQL-CREATERULE-4">
|
|
<title>
|
|
Compatibility
|
|
</title>
|
|
|
|
<refsect2 id="R2-SQL-CREATERULE-4">
|
|
<refsect2info>
|
|
<date>1998-09-11</date>
|
|
</refsect2info>
|
|
<title>
|
|
SQL92
|
|
</title>
|
|
|
|
<para>
|
|
<command>CREATE RULE</command> statement is a <productname>Postgres</productname>
|
|
language extension.
|
|
There is no <command>CREATE RULE</command> statement in <acronym>SQL92</acronym>.
|
|
</para>
|
|
</refsect2>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:nil
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"../reference.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:"/usr/lib/sgml/catalog"
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
-->
|