]> begriffs open source - ai-pg/blob - full-docs/txt/rules-views.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / rules-views.txt
1
2 39.2. Views and the Rule System #
3
4    39.2.1. How SELECT Rules Work
5    39.2.2. View Rules in Non-SELECT Statements
6    39.2.3. The Power of Views in PostgreSQL
7    39.2.4. Updating a View
8
9    Views in PostgreSQL are implemented using the rule system. A view is
10    basically an empty table (having no actual storage) with an ON SELECT
11    DO INSTEAD rule. Conventionally, that rule is named _RETURN. So a view
12    like
13 CREATE VIEW myview AS SELECT * FROM mytab;
14
15    is very nearly the same thing as
16 CREATE TABLE myview (same column list as mytab);
17 CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
18     SELECT * FROM mytab;
19
20    although you can't actually write that, because tables are not allowed
21    to have ON SELECT rules.
22
23    A view can also have other kinds of DO INSTEAD rules, allowing INSERT,
24    UPDATE, or DELETE commands to be performed on the view despite its lack
25    of underlying storage. This is discussed further below, in
26    Section 39.2.4.
27
28 39.2.1. How SELECT Rules Work #
29
30    Rules ON SELECT are applied to all queries as the last step, even if
31    the command given is an INSERT, UPDATE or DELETE. And they have
32    different semantics from rules on the other command types in that they
33    modify the query tree in place instead of creating a new one. So SELECT
34    rules are described first.
35
36    Currently, there can be only one action in an ON SELECT rule, and it
37    must be an unconditional SELECT action that is INSTEAD. This
38    restriction was required to make rules safe enough to open them for
39    ordinary users, and it restricts ON SELECT rules to act like views.
40
41    The examples for this chapter are two join views that do some
42    calculations and some more views using them in turn. One of the two
43    first views is customized later by adding rules for INSERT, UPDATE, and
44    DELETE operations so that the final result will be a view that behaves
45    like a real table with some magic functionality. This is not such a
46    simple example to start from and this makes things harder to get into.
47    But it's better to have one example that covers all the points
48    discussed step by step rather than having many different ones that
49    might mix up in mind.
50
51    The real tables we need in the first two rule system descriptions are
52    these:
53 CREATE TABLE shoe_data (
54     shoename   text,          -- primary key
55     sh_avail   integer,       -- available number of pairs
56     slcolor    text,          -- preferred shoelace color
57     slminlen   real,          -- minimum shoelace length
58     slmaxlen   real,          -- maximum shoelace length
59     slunit     text           -- length unit
60 );
61
62 CREATE TABLE shoelace_data (
63     sl_name    text,          -- primary key
64     sl_avail   integer,       -- available number of pairs
65     sl_color   text,          -- shoelace color
66     sl_len     real,          -- shoelace length
67     sl_unit    text           -- length unit
68 );
69
70 CREATE TABLE unit (
71     un_name    text,          -- primary key
72     un_fact    real           -- factor to transform to cm
73 );
74
75    As you can see, they represent shoe-store data.
76
77    The views are created as:
78 CREATE VIEW shoe AS
79     SELECT sh.shoename,
80            sh.sh_avail,
81            sh.slcolor,
82            sh.slminlen,
83            sh.slminlen * un.un_fact AS slminlen_cm,
84            sh.slmaxlen,
85            sh.slmaxlen * un.un_fact AS slmaxlen_cm,
86            sh.slunit
87       FROM shoe_data sh, unit un
88      WHERE sh.slunit = un.un_name;
89
90 CREATE VIEW shoelace AS
91     SELECT s.sl_name,
92            s.sl_avail,
93            s.sl_color,
94            s.sl_len,
95            s.sl_unit,
96            s.sl_len * u.un_fact AS sl_len_cm
97       FROM shoelace_data s, unit u
98      WHERE s.sl_unit = u.un_name;
99
100 CREATE VIEW shoe_ready AS
101     SELECT rsh.shoename,
102            rsh.sh_avail,
103            rsl.sl_name,
104            rsl.sl_avail,
105            least(rsh.sh_avail, rsl.sl_avail) AS total_avail
106       FROM shoe rsh, shoelace rsl
107      WHERE rsl.sl_color = rsh.slcolor
108        AND rsl.sl_len_cm >= rsh.slminlen_cm
109        AND rsl.sl_len_cm <= rsh.slmaxlen_cm;
110
111    The CREATE VIEW command for the shoelace view (which is the simplest
112    one we have) will create a relation shoelace and an entry in pg_rewrite
113    that tells that there is a rewrite rule that must be applied whenever
114    the relation shoelace is referenced in a query's range table. The rule
115    has no rule qualification (discussed later, with the non-SELECT rules,
116    since SELECT rules currently cannot have them) and it is INSTEAD. Note
117    that rule qualifications are not the same as query qualifications. The
118    action of our rule has a query qualification. The action of the rule is
119    one query tree that is a copy of the SELECT statement in the view
120    creation command.
121
122 Note
123
124    The two extra range table entries for NEW and OLD that you can see in
125    the pg_rewrite entry aren't of interest for SELECT rules.
126
127    Now we populate unit, shoe_data and shoelace_data and run a simple
128    query on a view:
129 INSERT INTO unit VALUES ('cm', 1.0);
130 INSERT INTO unit VALUES ('m', 100.0);
131 INSERT INTO unit VALUES ('inch', 2.54);
132
133 INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm');
134 INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch');
135 INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm');
136 INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch');
137
138 INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm');
139 INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm');
140 INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch');
141 INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch');
142 INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm');
143 INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm');
144 INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm');
145 INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch');
146
147 SELECT * FROM shoelace;
148
149  sl_name   | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
150 -----------+----------+----------+--------+---------+-----------
151  sl1       |        5 | black    |     80 | cm      |        80
152  sl2       |        6 | black    |    100 | cm      |       100
153  sl7       |        7 | brown    |     60 | cm      |        60
154  sl3       |        0 | black    |     35 | inch    |      88.9
155  sl4       |        8 | black    |     40 | inch    |     101.6
156  sl8       |        1 | brown    |     40 | inch    |     101.6
157  sl5       |        4 | brown    |      1 | m       |       100
158  sl6       |        0 | brown    |    0.9 | m       |        90
159 (8 rows)
160
161    This is the simplest SELECT you can do on our views, so we take this
162    opportunity to explain the basics of view rules. The SELECT * FROM
163    shoelace was interpreted by the parser and produced the query tree:
164 SELECT shoelace.sl_name, shoelace.sl_avail,
165        shoelace.sl_color, shoelace.sl_len,
166        shoelace.sl_unit, shoelace.sl_len_cm
167   FROM shoelace shoelace;
168
169    and this is given to the rule system. The rule system walks through the
170    range table and checks if there are rules for any relation. When
171    processing the range table entry for shoelace (the only one up to now)
172    it finds the _RETURN rule with the query tree:
173 SELECT s.sl_name, s.sl_avail,
174        s.sl_color, s.sl_len, s.sl_unit,
175        s.sl_len * u.un_fact AS sl_len_cm
176   FROM shoelace old, shoelace new,
177        shoelace_data s, unit u
178  WHERE s.sl_unit = u.un_name;
179
180    To expand the view, the rewriter simply creates a subquery range-table
181    entry containing the rule's action query tree, and substitutes this
182    range table entry for the original one that referenced the view. The
183    resulting rewritten query tree is almost the same as if you had typed:
184 SELECT shoelace.sl_name, shoelace.sl_avail,
185        shoelace.sl_color, shoelace.sl_len,
186        shoelace.sl_unit, shoelace.sl_len_cm
187   FROM (SELECT s.sl_name,
188                s.sl_avail,
189                s.sl_color,
190                s.sl_len,
191                s.sl_unit,
192                s.sl_len * u.un_fact AS sl_len_cm
193           FROM shoelace_data s, unit u
194          WHERE s.sl_unit = u.un_name) shoelace;
195
196    There is one difference however: the subquery's range table has two
197    extra entries shoelace old and shoelace new. These entries don't
198    participate directly in the query, since they aren't referenced by the
199    subquery's join tree or target list. The rewriter uses them to store
200    the access privilege check information that was originally present in
201    the range-table entry that referenced the view. In this way, the
202    executor will still check that the user has proper privileges to access
203    the view, even though there's no direct use of the view in the
204    rewritten query.
205
206    That was the first rule applied. The rule system will continue checking
207    the remaining range-table entries in the top query (in this example
208    there are no more), and it will recursively check the range-table
209    entries in the added subquery to see if any of them reference views.
210    (But it won't expand old or new — otherwise we'd have infinite
211    recursion!) In this example, there are no rewrite rules for
212    shoelace_data or unit, so rewriting is complete and the above is the
213    final result given to the planner.
214
215    Now we want to write a query that finds out for which shoes currently
216    in the store we have the matching shoelaces (color and length) and
217    where the total number of exactly matching pairs is greater than or
218    equal to two.
219 SELECT * FROM shoe_ready WHERE total_avail >= 2;
220
221  shoename | sh_avail | sl_name | sl_avail | total_avail
222 ----------+----------+---------+----------+-------------
223  sh1      |        2 | sl1     |        5 |           2
224  sh3      |        4 | sl7     |        7 |           4
225 (2 rows)
226
227    The output of the parser this time is the query tree:
228 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
229        shoe_ready.sl_name, shoe_ready.sl_avail,
230        shoe_ready.total_avail
231   FROM shoe_ready shoe_ready
232  WHERE shoe_ready.total_avail >= 2;
233
234    The first rule applied will be the one for the shoe_ready view and it
235    results in the query tree:
236 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
237        shoe_ready.sl_name, shoe_ready.sl_avail,
238        shoe_ready.total_avail
239   FROM (SELECT rsh.shoename,
240                rsh.sh_avail,
241                rsl.sl_name,
242                rsl.sl_avail,
243                least(rsh.sh_avail, rsl.sl_avail) AS total_avail
244           FROM shoe rsh, shoelace rsl
245          WHERE rsl.sl_color = rsh.slcolor
246            AND rsl.sl_len_cm >= rsh.slminlen_cm
247            AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
248  WHERE shoe_ready.total_avail >= 2;
249
250    Similarly, the rules for shoe and shoelace are substituted into the
251    range table of the subquery, leading to a three-level final query tree:
252 SELECT shoe_ready.shoename, shoe_ready.sh_avail,
253        shoe_ready.sl_name, shoe_ready.sl_avail,
254        shoe_ready.total_avail
255   FROM (SELECT rsh.shoename,
256                rsh.sh_avail,
257                rsl.sl_name,
258                rsl.sl_avail,
259                least(rsh.sh_avail, rsl.sl_avail) AS total_avail
260           FROM (SELECT sh.shoename,
261                        sh.sh_avail,
262                        sh.slcolor,
263                        sh.slminlen,
264                        sh.slminlen * un.un_fact AS slminlen_cm,
265                        sh.slmaxlen,
266                        sh.slmaxlen * un.un_fact AS slmaxlen_cm,
267                        sh.slunit
268                   FROM shoe_data sh, unit un
269                  WHERE sh.slunit = un.un_name) rsh,
270                (SELECT s.sl_name,
271                        s.sl_avail,
272                        s.sl_color,
273                        s.sl_len,
274                        s.sl_unit,
275                        s.sl_len * u.un_fact AS sl_len_cm
276                   FROM shoelace_data s, unit u
277                  WHERE s.sl_unit = u.un_name) 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;
282
283    This might look inefficient, but the planner will collapse this into a
284    single-level query tree by “pulling up” the subqueries, and then it
285    will plan the joins just as if we'd written them out manually. So
286    collapsing the query tree is an optimization that the rewrite system
287    doesn't have to concern itself with.
288
289 39.2.2. View Rules in Non-SELECT Statements #
290
291    Two details of the query tree aren't touched in the description of view
292    rules above. These are the command type and the result relation. In
293    fact, the command type is not needed by view rules, but the result
294    relation may affect the way in which the query rewriter works, because
295    special care needs to be taken if the result relation is a view.
296
297    There are only a few differences between a query tree for a SELECT and
298    one for any other command. Obviously, they have a different command
299    type and for a command other than a SELECT, the result relation points
300    to the range-table entry where the result should go. Everything else is
301    absolutely the same. So having two tables t1 and t2 with columns a and
302    b, the query trees for the two statements:
303 SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;
304
305 UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
306
307    are nearly identical. In particular:
308      * The range tables contain entries for the tables t1 and t2.
309      * The target lists contain one variable that points to column b of
310        the range table entry for table t2.
311      * The qualification expressions compare the columns a of both
312        range-table entries for equality.
313      * The join trees show a simple join between t1 and t2.
314
315    The consequence is, that both query trees result in similar execution
316    plans: They are both joins over the two tables. For the UPDATE the
317    missing columns from t1 are added to the target list by the planner and
318    the final query tree will read as:
319 UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
320
321    and thus the executor run over the join will produce exactly the same
322    result set as:
323 SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
324
325    But there is a little problem in UPDATE: the part of the executor plan
326    that does the join does not care what the results from the join are
327    meant for. It just produces a result set of rows. The fact that one is
328    a SELECT command and the other is an UPDATE is handled higher up in the
329    executor, where it knows that this is an UPDATE, and it knows that this
330    result should go into table t1. But which of the rows that are there
331    has to be replaced by the new row?
332
333    To resolve this problem, another entry is added to the target list in
334    UPDATE (and also in DELETE) statements: the current tuple ID (CTID).
335    This is a system column containing the file block number and position
336    in the block for the row. Knowing the table, the CTID can be used to
337    retrieve the original row of t1 to be updated. After adding the CTID to
338    the target list, the query actually looks like:
339 SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a;
340
341    Now another detail of PostgreSQL enters the stage. Old table rows
342    aren't overwritten, and this is why ROLLBACK is fast. In an UPDATE, the
343    new result row is inserted into the table (after stripping the CTID)
344    and in the row header of the old row, which the CTID pointed to, the
345    cmax and xmax entries are set to the current command counter and
346    current transaction ID. Thus the old row is hidden, and after the
347    transaction commits the vacuum cleaner can eventually remove the dead
348    row.
349
350    Knowing all that, we can simply apply view rules in absolutely the same
351    way to any command. There is no difference.
352
353 39.2.3. The Power of Views in PostgreSQL #
354
355    The above demonstrates how the rule system incorporates view
356    definitions into the original query tree. In the second example, a
357    simple SELECT from one view created a final query tree that is a join
358    of 4 tables (unit was used twice with different names).
359
360    The benefit of implementing views with the rule system is that the
361    planner has all the information about which tables have to be scanned
362    plus the relationships between these tables plus the restrictive
363    qualifications from the views plus the qualifications from the original
364    query in one single query tree. And this is still the situation when
365    the original query is already a join over views. The planner has to
366    decide which is the best path to execute the query, and the more
367    information the planner has, the better this decision can be. And the
368    rule system as implemented in PostgreSQL ensures that this is all
369    information available about the query up to that point.
370
371 39.2.4. Updating a View #
372
373    What happens if a view is named as the target relation for an INSERT,
374    UPDATE, DELETE, or MERGE? Doing the substitutions described above would
375    give a query tree in which the result relation points at a subquery
376    range-table entry, which will not work. There are several ways in which
377    PostgreSQL can support the appearance of updating a view, however. In
378    order of user-experienced complexity those are: automatically
379    substitute in the underlying table for the view, execute a user-defined
380    trigger, or rewrite the query per a user-defined rule. These options
381    are discussed below.
382
383    If the subquery selects from a single base relation and is simple
384    enough, the rewriter can automatically replace the subquery with the
385    underlying base relation so that the INSERT, UPDATE, DELETE, or MERGE
386    is applied to the base relation in the appropriate way. Views that are
387    “simple enough” for this are called automatically updatable. For
388    detailed information on the kinds of view that can be automatically
389    updated, see CREATE VIEW.
390
391    Alternatively, the operation may be handled by a user-provided INSTEAD
392    OF trigger on the view (see CREATE TRIGGER). Rewriting works slightly
393    differently in this case. For INSERT, the rewriter does nothing at all
394    with the view, leaving it as the result relation for the query. For
395    UPDATE, DELETE, and MERGE, it's still necessary to expand the view
396    query to produce the “old” rows that the command will attempt to
397    update, delete, or merge. So the view is expanded as normal, but
398    another unexpanded range-table entry is added to the query to represent
399    the view in its capacity as the result relation.
400
401    The problem that now arises is how to identify the rows to be updated
402    in the view. Recall that when the result relation is a table, a special
403    CTID entry is added to the target list to identify the physical
404    locations of the rows to be updated. This does not work if the result
405    relation is a view, because a view does not have any CTID, since its
406    rows do not have actual physical locations. Instead, for an UPDATE,
407    DELETE, or MERGE operation, a special wholerow entry is added to the
408    target list, which expands to include all columns from the view. The
409    executor uses this value to supply the “old” row to the INSTEAD OF
410    trigger. It is up to the trigger to work out what to update based on
411    the old and new row values.
412
413    Another possibility is for the user to define INSTEAD rules that
414    specify substitute actions for INSERT, UPDATE, and DELETE commands on a
415    view. These rules will rewrite the command, typically into a command
416    that updates one or more tables, rather than views. That is the topic
417    of Section 39.4. Note that this will not work with MERGE, which
418    currently does not support rules on the target relation other than
419    SELECT rules.
420
421    Note that rules are evaluated first, rewriting the original query
422    before it is planned and executed. Therefore, if a view has INSTEAD OF
423    triggers as well as rules on INSERT, UPDATE, or DELETE, then the rules
424    will be evaluated first, and depending on the result, the triggers may
425    not be used at all.
426
427    Automatic rewriting of an INSERT, UPDATE, DELETE, or MERGE query on a
428    simple view is always tried last. Therefore, if a view has rules or
429    triggers, they will override the default behavior of automatically
430    updatable views.
431
432    If there are no INSTEAD rules or INSTEAD OF triggers for the view, and
433    the rewriter cannot automatically rewrite the query as an update on the
434    underlying base relation, an error will be thrown because the executor
435    cannot update a view as such.