1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>39.2. Views and the Rule System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="querytree.html" title="39.1. The Query Tree" /><link rel="next" href="rules-materializedviews.html" title="39.3. Materialized Views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">39.2. Views and the Rule System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="querytree.html" title="39.1. The Query Tree">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 39. The Rule System">Up</a></td><th width="60%" align="center">Chapter 39. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-materializedviews.html" title="39.3. Materialized Views">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-VIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">39.2. Views and the Rule System <a href="#RULES-VIEWS" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="rules-views.html#RULES-SELECT">39.2.1. How <code class="command">SELECT</code> Rules Work</a></span></dt><dt><span class="sect2"><a href="rules-views.html#RULES-VIEWS-NON-SELECT">39.2.2. View Rules in Non-<code class="command">SELECT</code> Statements</a></span></dt><dt><span class="sect2"><a href="rules-views.html#RULES-VIEWS-POWER">39.2.3. The Power of Views in <span class="productname">PostgreSQL</span></a></span></dt><dt><span class="sect2"><a href="rules-views.html#RULES-VIEWS-UPDATE">39.2.4. Updating a View</a></span></dt></dl></div><a id="id-1.8.6.7.2" class="indexterm"></a><a id="id-1.8.6.7.3" class="indexterm"></a><p>
3 Views in <span class="productname">PostgreSQL</span> are implemented
4 using the rule system. A view is basically an empty table (having no
5 actual storage) with an <code class="literal">ON SELECT DO INSTEAD</code> rule.
6 Conventionally, that rule is named <code class="literal">_RETURN</code>.
9 </p><pre class="programlisting">
10 CREATE VIEW myview AS SELECT * FROM mytab;
13 is very nearly the same thing as
15 </p><pre class="programlisting">
16 CREATE TABLE myview (<em class="replaceable"><code>same column list as mytab</code></em>);
17 CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
21 although you can't actually write that, because tables are not
22 allowed to have <code class="literal">ON SELECT</code> rules.
24 A view can also have other kinds of <code class="literal">DO INSTEAD</code>
25 rules, allowing <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
26 or <code class="command">DELETE</code> commands to be performed on the view
27 despite its lack of underlying storage.
28 This is discussed further below, in
29 <a class="xref" href="rules-views.html#RULES-VIEWS-UPDATE" title="39.2.4. Updating a View">Section 39.2.4</a>.
30 </p><div class="sect2" id="RULES-SELECT"><div class="titlepage"><div><div><h3 class="title">39.2.1. How <code class="command">SELECT</code> Rules Work <a href="#RULES-SELECT" class="id_link">#</a></h3></div></div></div><a id="id-1.8.6.7.6.2" class="indexterm"></a><p>
31 Rules <code class="literal">ON SELECT</code> are applied to all queries as the last step, even
32 if the command given is an <code class="command">INSERT</code>,
33 <code class="command">UPDATE</code> or <code class="command">DELETE</code>. And they
34 have different semantics from rules on the other command types in that they modify the
35 query tree in place instead of creating a new one. So
36 <code class="command">SELECT</code> rules are described first.
38 Currently, there can be only one action in an <code class="literal">ON SELECT</code> rule, and it must
39 be an unconditional <code class="command">SELECT</code> action that is <code class="literal">INSTEAD</code>. This restriction was
40 required to make rules safe enough to open them for ordinary users, and
41 it restricts <code class="literal">ON SELECT</code> rules to act like views.
43 The examples for this chapter are two join views that do some
44 calculations and some more views using them in turn. One of the
45 two first views is customized later by adding rules for
46 <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
47 <code class="command">DELETE</code> operations so that the final result will
48 be a view that behaves like a real table with some magic
49 functionality. This is not such a simple example to start from and
50 this makes things harder to get into. But it's better to have one
51 example that covers all the points discussed step by step rather
52 than having many different ones that might mix up in mind.
54 The real tables we need in the first two rule system descriptions
57 </p><pre class="programlisting">
58 CREATE TABLE shoe_data (
59 shoename text, -- primary key
60 sh_avail integer, -- available number of pairs
61 slcolor text, -- preferred shoelace color
62 slminlen real, -- minimum shoelace length
63 slmaxlen real, -- maximum shoelace length
64 slunit text -- length unit
67 CREATE TABLE shoelace_data (
68 sl_name text, -- primary key
69 sl_avail integer, -- available number of pairs
70 sl_color text, -- shoelace color
71 sl_len real, -- shoelace length
72 sl_unit text -- length unit
76 un_name text, -- primary key
77 un_fact real -- factor to transform to cm
81 As you can see, they represent shoe-store data.
83 The views are created as:
85 </p><pre class="programlisting">
91 sh.slminlen * un.un_fact AS slminlen_cm,
93 sh.slmaxlen * un.un_fact AS slmaxlen_cm,
95 FROM shoe_data sh, unit un
96 WHERE sh.slunit = un.un_name;
98 CREATE VIEW shoelace AS
104 s.sl_len * u.un_fact AS sl_len_cm
105 FROM shoelace_data s, unit u
106 WHERE s.sl_unit = u.un_name;
108 CREATE VIEW shoe_ready AS
113 least(rsh.sh_avail, rsl.sl_avail) AS total_avail
114 FROM shoe rsh, shoelace rsl
115 WHERE rsl.sl_color = rsh.slcolor
116 AND rsl.sl_len_cm >= rsh.slminlen_cm
117 AND rsl.sl_len_cm <= rsh.slmaxlen_cm;
120 The <code class="command">CREATE VIEW</code> command for the
121 <code class="literal">shoelace</code> view (which is the simplest one we
122 have) will create a relation <code class="literal">shoelace</code> and an entry in
123 <code class="structname">pg_rewrite</code> that tells that there is a
124 rewrite rule that must be applied whenever the relation <code class="literal">shoelace</code>
125 is referenced in a query's range table. The rule has no rule
126 qualification (discussed later, with the non-<code class="command">SELECT</code> rules, since
127 <code class="command">SELECT</code> rules currently cannot have them) and it is <code class="literal">INSTEAD</code>. Note
128 that rule qualifications are not the same as query qualifications.
129 The action of our rule has a query qualification.
130 The action of the rule is one query tree that is a copy of the
131 <code class="command">SELECT</code> statement in the view creation command.
132 </p><div class="note"><h3 class="title">Note</h3><p>
134 table entries for <code class="literal">NEW</code> and <code class="literal">OLD</code> that you can see in
135 the <code class="structname">pg_rewrite</code> entry aren't of interest
136 for <code class="command">SELECT</code> rules.
138 Now we populate <code class="literal">unit</code>, <code class="literal">shoe_data</code>
139 and <code class="literal">shoelace_data</code> and run a simple query on a view:
141 </p><pre class="programlisting">
142 INSERT INTO unit VALUES ('cm', 1.0);
143 INSERT INTO unit VALUES ('m', 100.0);
144 INSERT INTO unit VALUES ('inch', 2.54);
146 INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm');
147 INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch');
148 INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm');
149 INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch');
151 INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm');
152 INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm');
153 INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch');
154 INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch');
155 INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm');
156 INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm');
157 INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm');
158 INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch');
160 SELECT * FROM shoelace;
162 sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
163 -----------+----------+----------+--------+---------+-----------
164 sl1 | 5 | black | 80 | cm | 80
165 sl2 | 6 | black | 100 | cm | 100
166 sl7 | 7 | brown | 60 | cm | 60
167 sl3 | 0 | black | 35 | inch | 88.9
168 sl4 | 8 | black | 40 | inch | 101.6
169 sl8 | 1 | brown | 40 | inch | 101.6
170 sl5 | 4 | brown | 1 | m | 100
171 sl6 | 0 | brown | 0.9 | m | 90
175 This is the simplest <code class="command">SELECT</code> you can do on our
176 views, so we take this opportunity to explain the basics of view
177 rules. The <code class="literal">SELECT * FROM shoelace</code> was
178 interpreted by the parser and produced the query tree:
180 </p><pre class="programlisting">
181 SELECT shoelace.sl_name, shoelace.sl_avail,
182 shoelace.sl_color, shoelace.sl_len,
183 shoelace.sl_unit, shoelace.sl_len_cm
184 FROM shoelace shoelace;
187 and this is given to the rule system. The rule system walks through the
188 range table and checks if there are rules
189 for any relation. When processing the range table entry for
190 <code class="literal">shoelace</code> (the only one up to now) it finds the
191 <code class="literal">_RETURN</code> rule with the query tree:
193 </p><pre class="programlisting">
194 SELECT s.sl_name, s.sl_avail,
195 s.sl_color, s.sl_len, s.sl_unit,
196 s.sl_len * u.un_fact AS sl_len_cm
197 FROM shoelace old, shoelace new,
198 shoelace_data s, unit u
199 WHERE s.sl_unit = u.un_name;
202 To expand the view, the rewriter simply creates a subquery range-table
203 entry containing the rule's action query tree, and substitutes this
204 range table entry for the original one that referenced the view. The
205 resulting rewritten query tree is almost the same as if you had typed:
207 </p><pre class="programlisting">
208 SELECT shoelace.sl_name, shoelace.sl_avail,
209 shoelace.sl_color, shoelace.sl_len,
210 shoelace.sl_unit, shoelace.sl_len_cm
211 FROM (SELECT s.sl_name,
216 s.sl_len * u.un_fact AS sl_len_cm
217 FROM shoelace_data s, unit u
218 WHERE s.sl_unit = u.un_name) shoelace;
221 There is one difference however: the subquery's range table has two
222 extra entries <code class="literal">shoelace old</code> and <code class="literal">shoelace new</code>. These entries don't
223 participate directly in the query, since they aren't referenced by
224 the subquery's join tree or target list. The rewriter uses them
225 to store the access privilege check information that was originally present
226 in the range-table entry that referenced the view. In this way, the
227 executor will still check that the user has proper privileges to access
228 the view, even though there's no direct use of the view in the rewritten
231 That was the first rule applied. The rule system will continue checking
232 the remaining range-table entries in the top query (in this example there
233 are no more), and it will recursively check the range-table entries in
234 the added subquery to see if any of them reference views. (But it
235 won't expand <code class="literal">old</code> or <code class="literal">new</code> — otherwise we'd have infinite recursion!)
236 In this example, there are no rewrite rules for <code class="literal">shoelace_data</code> or <code class="literal">unit</code>,
237 so rewriting is complete and the above is the final result given to
240 Now we want to write a query that finds out for which shoes currently in the store
241 we have the matching shoelaces (color and length) and where the
242 total number of exactly matching pairs is greater than or equal to two.
244 </p><pre class="programlisting">
245 SELECT * FROM shoe_ready WHERE total_avail >= 2;
247 shoename | sh_avail | sl_name | sl_avail | total_avail
248 ----------+----------+---------+----------+-------------
249 sh1 | 2 | sl1 | 5 | 2
250 sh3 | 4 | sl7 | 7 | 4
254 The output of the parser this time is the query tree:
256 </p><pre class="programlisting">
257 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
258 shoe_ready.sl_name, shoe_ready.sl_avail,
259 shoe_ready.total_avail
260 FROM shoe_ready shoe_ready
261 WHERE shoe_ready.total_avail >= 2;
264 The first rule applied will be the one for the
265 <code class="literal">shoe_ready</code> view and it results in the
268 </p><pre class="programlisting">
269 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
270 shoe_ready.sl_name, shoe_ready.sl_avail,
271 shoe_ready.total_avail
272 FROM (SELECT rsh.shoename,
276 least(rsh.sh_avail, rsl.sl_avail) AS total_avail
277 FROM shoe rsh, shoelace rsl
278 WHERE rsl.sl_color = rsh.slcolor
279 AND rsl.sl_len_cm >= rsh.slminlen_cm
280 AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
281 WHERE shoe_ready.total_avail >= 2;
284 Similarly, the rules for <code class="literal">shoe</code> and
285 <code class="literal">shoelace</code> are substituted into the range table of
286 the subquery, leading to a three-level final query tree:
288 </p><pre class="programlisting">
289 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
290 shoe_ready.sl_name, shoe_ready.sl_avail,
291 shoe_ready.total_avail
292 FROM (SELECT rsh.shoename,
296 least(rsh.sh_avail, rsl.sl_avail) AS total_avail
297 FROM (SELECT sh.shoename,
301 sh.slminlen * un.un_fact AS slminlen_cm,
303 sh.slmaxlen * un.un_fact AS slmaxlen_cm,
305 FROM shoe_data sh, unit un
306 WHERE sh.slunit = un.un_name) rsh,
312 s.sl_len * u.un_fact AS sl_len_cm
313 FROM shoelace_data s, unit u
314 WHERE s.sl_unit = u.un_name) rsl
315 WHERE rsl.sl_color = rsh.slcolor
316 AND rsl.sl_len_cm >= rsh.slminlen_cm
317 AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
318 WHERE shoe_ready.total_avail > 2;
321 This might look inefficient, but the planner will collapse this into a
322 single-level query tree by <span class="quote">“<span class="quote">pulling up</span>”</span> the subqueries,
323 and then it will plan the joins just as if we'd written them out
324 manually. So collapsing the query tree is an optimization that the
325 rewrite system doesn't have to concern itself with.
326 </p></div><div class="sect2" id="RULES-VIEWS-NON-SELECT"><div class="titlepage"><div><div><h3 class="title">39.2.2. View Rules in Non-<code class="command">SELECT</code> Statements <a href="#RULES-VIEWS-NON-SELECT" class="id_link">#</a></h3></div></div></div><p>
327 Two details of the query tree aren't touched in the description of
328 view rules above. These are the command type and the result relation.
329 In fact, the command type is not needed by view rules, but the result
330 relation may affect the way in which the query rewriter works, because
331 special care needs to be taken if the result relation is a view.
333 There are only a few differences between a query tree for a
334 <code class="command">SELECT</code> and one for any other
335 command. Obviously, they have a different command type and for a
336 command other than a <code class="command">SELECT</code>, the result
337 relation points to the range-table entry where the result should
338 go. Everything else is absolutely the same. So having two tables
339 <code class="literal">t1</code> and <code class="literal">t2</code> with columns <code class="literal">a</code> and
340 <code class="literal">b</code>, the query trees for the two statements:
342 </p><pre class="programlisting">
343 SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;
345 UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
348 are nearly identical. In particular:
350 </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
351 The range tables contain entries for the tables <code class="literal">t1</code> and <code class="literal">t2</code>.
352 </p></li><li class="listitem"><p>
353 The target lists contain one variable that points to column
354 <code class="literal">b</code> of the range table entry for table <code class="literal">t2</code>.
355 </p></li><li class="listitem"><p>
356 The qualification expressions compare the columns <code class="literal">a</code> of both
357 range-table entries for equality.
358 </p></li><li class="listitem"><p>
359 The join trees show a simple join between <code class="literal">t1</code> and <code class="literal">t2</code>.
360 </p></li></ul></div><p>
362 The consequence is, that both query trees result in similar
363 execution plans: They are both joins over the two tables. For the
364 <code class="command">UPDATE</code> the missing columns from <code class="literal">t1</code> are added to
365 the target list by the planner and the final query tree will read
368 </p><pre class="programlisting">
369 UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
372 and thus the executor run over the join will produce exactly the
375 </p><pre class="programlisting">
376 SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
379 But there is a little problem in
380 <code class="command">UPDATE</code>: the part of the executor plan that does
381 the join does not care what the results from the join are
382 meant for. It just produces a result set of rows. The fact that
383 one is a <code class="command">SELECT</code> command and the other is an
384 <code class="command">UPDATE</code> is handled higher up in the executor, where
385 it knows that this is an <code class="command">UPDATE</code>, and it knows that
386 this result should go into table <code class="literal">t1</code>. But which of the rows
387 that are there has to be replaced by the new row?
389 To resolve this problem, another entry is added to the target list
390 in <code class="command">UPDATE</code> (and also in
391 <code class="command">DELETE</code>) statements: the current tuple ID
392 (<acronym class="acronym">CTID</acronym>).<a id="id-1.8.6.7.7.5.4" class="indexterm"></a>
393 This is a system column containing the
394 file block number and position in the block for the row. Knowing
395 the table, the <acronym class="acronym">CTID</acronym> can be used to retrieve the
396 original row of <code class="literal">t1</code> to be updated. After adding the
397 <acronym class="acronym">CTID</acronym> to the target list, the query actually looks like:
399 </p><pre class="programlisting">
400 SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a;
403 Now another detail of <span class="productname">PostgreSQL</span> enters
404 the stage. Old table rows aren't overwritten, and this
405 is why <code class="command">ROLLBACK</code> is fast. In an <code class="command">UPDATE</code>,
406 the new result row is inserted into the table (after stripping the
407 <acronym class="acronym">CTID</acronym>) and in the row header of the old row, which the
408 <acronym class="acronym">CTID</acronym> pointed to, the <code class="literal">cmax</code> and
409 <code class="literal">xmax</code> entries are set to the current command counter
410 and current transaction ID. Thus the old row is hidden, and after
411 the transaction commits the vacuum cleaner can eventually remove
414 Knowing all that, we can simply apply view rules in absolutely
415 the same way to any command. There is no difference.
416 </p></div><div class="sect2" id="RULES-VIEWS-POWER"><div class="titlepage"><div><div><h3 class="title">39.2.3. The Power of Views in <span class="productname">PostgreSQL</span> <a href="#RULES-VIEWS-POWER" class="id_link">#</a></h3></div></div></div><p>
417 The above demonstrates how the rule system incorporates view
418 definitions into the original query tree. In the second example, a
419 simple <code class="command">SELECT</code> from one view created a final
420 query tree that is a join of 4 tables (<code class="literal">unit</code> was used twice with
423 The benefit of implementing views with the rule system is
424 that the planner has all
425 the information about which tables have to be scanned plus the
426 relationships between these tables plus the restrictive
427 qualifications from the views plus the qualifications from
429 in one single query tree. And this is still the situation
430 when the original query is already a join over views.
431 The planner has to decide which is
432 the best path to execute the query, and the more information
433 the planner has, the better this decision can be. And
434 the rule system as implemented in <span class="productname">PostgreSQL</span>
435 ensures that this is all information available about the query
437 </p></div><div class="sect2" id="RULES-VIEWS-UPDATE"><div class="titlepage"><div><div><h3 class="title">39.2.4. Updating a View <a href="#RULES-VIEWS-UPDATE" class="id_link">#</a></h3></div></div></div><p>
438 What happens if a view is named as the target relation for an
439 <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
440 <code class="command">DELETE</code>, or <code class="command">MERGE</code>? Doing the
441 substitutions described above would give a query tree in which the result
442 relation points at a subquery range-table entry, which will not
443 work. There are several ways in which <span class="productname">PostgreSQL</span>
444 can support the appearance of updating a view, however.
445 In order of user-experienced complexity those are: automatically substitute
446 in the underlying table for the view, execute a user-defined trigger,
447 or rewrite the query per a user-defined rule.
448 These options are discussed below.
450 If the subquery selects from a single base relation and is simple
451 enough, the rewriter can automatically replace the subquery with the
452 underlying base relation so that the <code class="command">INSERT</code>,
453 <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or
454 <code class="command">MERGE</code> is applied to the base relation in the
455 appropriate way. Views that are <span class="quote">“<span class="quote">simple enough</span>”</span> for this
456 are called <em class="firstterm">automatically updatable</em>. For detailed
457 information on the kinds of view that can be automatically updated, see
458 <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>.
460 Alternatively, the operation may be handled by a user-provided
461 <code class="literal">INSTEAD OF</code> trigger on the view
462 (see <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>).
463 Rewriting works slightly differently
464 in this case. For <code class="command">INSERT</code>, the rewriter does
465 nothing at all with the view, leaving it as the result relation
466 for the query. For <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
467 and <code class="command">MERGE</code>, it's still necessary to expand the
468 view query to produce the <span class="quote">“<span class="quote">old</span>”</span> rows that the command will
469 attempt to update, delete, or merge. So the view is expanded as normal,
470 but another unexpanded range-table entry is added to the query
471 to represent the view in its capacity as the result relation.
473 The problem that now arises is how to identify the rows to be
474 updated in the view. Recall that when the result relation
475 is a table, a special <acronym class="acronym">CTID</acronym> entry is added to the target
476 list to identify the physical locations of the rows to be updated.
477 This does not work if the result relation is a view, because a view
478 does not have any <acronym class="acronym">CTID</acronym>, since its rows do not have
479 actual physical locations. Instead, for an <code class="command">UPDATE</code>,
480 <code class="command">DELETE</code>, or <code class="command">MERGE</code> operation, a
481 special <code class="literal">wholerow</code> entry is added to the target list,
482 which expands to include all columns from the view. The executor uses this
483 value to supply the <span class="quote">“<span class="quote">old</span>”</span> row to the
484 <code class="literal">INSTEAD OF</code> trigger. It is up to the trigger to work
485 out what to update based on the old and new row values.
487 Another possibility is for the user to define <code class="literal">INSTEAD</code>
488 rules that specify substitute actions for <code class="command">INSERT</code>,
489 <code class="command">UPDATE</code>, and <code class="command">DELETE</code> commands on
490 a view. These rules will rewrite the command, typically into a command
491 that updates one or more tables, rather than views. That is the topic
492 of <a class="xref" href="rules-update.html" title="39.4. Rules on INSERT, UPDATE, and DELETE">Section 39.4</a>. Note that this will not work with
493 <code class="command">MERGE</code>, which currently does not support rules on
494 the target relation other than <code class="command">SELECT</code> rules.
496 Note that rules are evaluated first, rewriting the original query
497 before it is planned and executed. Therefore, if a view has
498 <code class="literal">INSTEAD OF</code> triggers as well as rules on <code class="command">INSERT</code>,
499 <code class="command">UPDATE</code>, or <code class="command">DELETE</code>, then the rules will be
500 evaluated first, and depending on the result, the triggers may not be
503 Automatic rewriting of an <code class="command">INSERT</code>,
504 <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or
505 <code class="command">MERGE</code> query on a
506 simple view is always tried last. Therefore, if a view has rules or
507 triggers, they will override the default behavior of automatically
510 If there are no <code class="literal">INSTEAD</code> rules or <code class="literal">INSTEAD OF</code>
511 triggers for the view, and the rewriter cannot automatically rewrite
512 the query as an update on the underlying base relation, an error will
513 be thrown because the executor cannot update a view as such.
514 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="querytree.html" title="39.1. The Query Tree">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 39. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-materializedviews.html" title="39.3. Materialized Views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">39.1. The Query Tree </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 39.3. Materialized Views</td></tr></table></div></body></html>