diff options
author | Tom Lane | 2012-12-08 23:25:48 +0000 |
---|---|---|
committer | Tom Lane | 2012-12-08 23:26:21 +0000 |
commit | a99c42f291421572aef2b0a9360294c7d89b8bc7 (patch) | |
tree | 330ccf97fb7318f988d8218bb1a854bc84025d63 /doc/src/sgml/rules.sgml | |
parent | d12d9f595e1c6bc6e62b7b423762fc03ad923899 (diff) |
Support automatically-updatable views.
This patch makes "simple" views automatically updatable, without the need
to create either INSTEAD OF triggers or INSTEAD rules. "Simple" views
are those classified as updatable according to SQL-92 rules. The rewriter
transforms INSERT/UPDATE/DELETE commands on such views directly into an
equivalent command on the underlying table, which will generally have
noticeably better performance than is possible with either triggers or
user-written rules. A view that has INSTEAD OF triggers or INSTEAD rules
continues to operate the same as before.
For the moment, security_barrier views are not considered simple.
Also, we do not support WITH CHECK OPTION. These features may be
added in future.
Dean Rasheed, reviewed by Amit Kapila
Diffstat (limited to 'doc/src/sgml/rules.sgml')
-rw-r--r-- | doc/src/sgml/rules.sgml | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml index cc02ada7c71..5811de7942f 100644 --- a/doc/src/sgml/rules.sgml +++ b/doc/src/sgml/rules.sgml @@ -808,13 +808,28 @@ SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a; <para> What happens if a view is named as the target relation for an <command>INSERT</command>, <command>UPDATE</command>, or - <command>DELETE</command>? Simply doing the substitutions + <command>DELETE</command>? Doing the substitutions described above would give a query tree in which the result relation points at a subquery range-table entry, which will not - work. Instead, the rewriter assumes that the operation will be - handled by an <literal>INSTEAD OF</> trigger on the view. - (If there is no such trigger, the executor will throw an error - when execution starts.) Rewriting works slightly differently + work. There are several ways in which <productname>PostgreSQL</> + can support the appearance of updating a view, however. +</para> + +<para> + If the subquery selects from a single base relation and is simple + enough, the rewriter can automatically replace the subquery with the + underlying base relation so that the <command>INSERT</command>, + <command>UPDATE</command>, or <command>DELETE</command> is applied to + the base relation in the appropriate way. Views that are + <quote>simple enough</> for this are called <firstterm>automatically + updatable</>. For detailed information on the kinds of view that can + be automatically updated, see <xref linkend="sql-createview">. +</para> + +<para> + Alternatively, the operation may be handled by a user-provided + <literal>INSTEAD OF</> trigger on the view. + Rewriting works slightly differently in this case. For <command>INSERT</command>, the rewriter does nothing at all with the view, leaving it as the result relation for the query. For <command>UPDATE</command> and @@ -842,10 +857,8 @@ SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a; </para> <para> - If there are no <literal>INSTEAD OF</> triggers to update the view, - the executor will throw an error, because it cannot automatically - update a view by itself. To change this, we can define rules that - modify the behavior of <command>INSERT</command>, + Another possibility is for the user to define <literal>INSTEAD</> + rules that specify substitute actions for <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command> commands on a view. These rules will rewrite the command, typically into a command that updates one or more tables, rather than views. That is the topic @@ -860,6 +873,22 @@ SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a; evaluated first, and depending on the result, the triggers may not be used at all. </para> + +<para> + Automatic rewriting of an <command>INSERT</command>, + <command>UPDATE</command>, or <command>DELETE</command> query on a + simple view is always tried last. Therefore, if a view has rules or + triggers, they will override the default behavior of automatically + updatable views. +</para> + +<para> + If there are no <literal>INSTEAD</> rules or <literal>INSTEAD OF</> + triggers for the view, and the rewriter cannot automatically rewrite + the query as an update on the underlying base relation, an error will + be thrown because the executor cannot update a view as such. +</para> + </sect2> </sect1> |