aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-10-14 22:14:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-10-14 22:14:35 +0000
commitd508b057ac0834eb6ea83b10ba9fd6c439b454a4 (patch)
treec100e9e56c25d3f6f57cd2be986b294258665a36 /doc/src
parentea3728ee5b60ee479caa865590d14f71f612dcdb (diff)
downloadpostgresql-d508b057ac0834eb6ea83b10ba9fd6c439b454a4.tar.gz
postgresql-d508b057ac0834eb6ea83b10ba9fd6c439b454a4.zip
Adjust handling of command status strings in the presence of rules,
as per recent pghackers discussions. initdb forced due to change in fields of stored Query nodes.
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/rules.sgml99
1 files changed, 71 insertions, 28 deletions
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml
index 493f2f05b82..50bcf3a4538 100644
--- a/doc/src/sgml/rules.sgml
+++ b/doc/src/sgml/rules.sgml
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/rules.sgml,v 1.24 2002/09/21 18:32:53 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/rules.sgml,v 1.25 2002/10/14 22:14:34 tgl Exp $ -->
<Chapter Id="rules">
<Title>The Rule System</Title>
@@ -189,7 +189,10 @@
In INSERT queries the target list describes the new rows that
should go into the result relation. It is the expressions in the VALUES
clause or the ones from the SELECT clause in INSERT ... SELECT.
- Missing columns of the result relation will be filled in by the
+ The first step of the rewrite process adds target list entries
+ for any columns that were not assigned to by the original query
+ and have defaults. Any remaining columns (with neither a given
+ value nor a default) will be filled in by the
planner with a constant NULL expression.
</Para>
@@ -197,7 +200,7 @@
In UPDATE queries, the target list describes the new rows that should
replace the old ones. In the rule system, it contains just the
expressions from the SET attribute = expression part of the query.
- The planner will add missing columns by inserting expressions that
+ The planner will handle missing columns by inserting expressions that
copy the values from the old row into the new one. And it will add
the special <acronym>CTID</> entry just as for DELETE too.
</Para>
@@ -278,8 +281,8 @@
<Para>
Views in <ProductName>PostgreSQL</ProductName> are implemented
- using the rule system. In fact there is absolutely no difference
- between a
+ using the rule system. In fact there is essentially no difference
+ between
<ProgramListing>
CREATE VIEW myview AS SELECT * FROM mytab;
@@ -1133,7 +1136,7 @@ int4ne(NEW.sl_avail, OLD.sl_avail)
<ProgramListing>
INSERT INTO shoelace_log VALUES(
*NEW*.sl_name, *NEW*.sl_avail,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*;
</ProgramListing>
@@ -1153,7 +1156,7 @@ INSERT INTO shoelace_log VALUES(
<ProgramListing>
INSERT INTO shoelace_log VALUES(
*NEW*.sl_name, *NEW*.sl_avail,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*,
<emphasis>shoelace_data shoelace_data</emphasis>;
</ProgramListing>
@@ -1164,7 +1167,7 @@ INSERT INTO shoelace_log VALUES(
<ProgramListing>
INSERT INTO shoelace_log VALUES(
*NEW*.sl_name, *NEW*.sl_avail,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*,
shoelace_data shoelace_data
<emphasis>WHERE int4ne(*NEW*.sl_avail, *OLD*.sl_avail)</emphasis>;
@@ -1174,7 +1177,9 @@ INSERT INTO shoelace_log VALUES(
a WHERE clause either, but the planner and executor will have no
difficulty with it. They need to support this same functionality
anyway for INSERT ... SELECT.
+ </para>
+ <para>
In step 3 the original parse tree's qualification is added,
restricting the result set further to only the rows touched
by the original parse tree.
@@ -1182,21 +1187,21 @@ INSERT INTO shoelace_log VALUES(
<ProgramListing>
INSERT INTO shoelace_log VALUES(
*NEW*.sl_name, *NEW*.sl_avail,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*,
shoelace_data shoelace_data
WHERE int4ne(*NEW*.sl_avail, *OLD*.sl_avail)
<emphasis>AND bpchareq(shoelace_data.sl_name, 'sl7')</emphasis>;
</ProgramListing>
- Step 4 substitutes NEW references by the target list entries from the
- original parse tree or with the matching variable references
+ Step 4 replaces NEW references by the target list entries from the
+ original parse tree or by the matching variable references
from the result relation.
<ProgramListing>
INSERT INTO shoelace_log VALUES(
<emphasis>shoelace_data.sl_name</emphasis>, <emphasis>6</emphasis>,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*,
shoelace_data shoelace_data
WHERE int4ne(<emphasis>6</emphasis>, *OLD*.sl_avail)
@@ -1208,7 +1213,7 @@ INSERT INTO shoelace_log VALUES(
<ProgramListing>
INSERT INTO shoelace_log VALUES(
shoelace_data.sl_name, 6,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data *NEW*, shoelace_data *OLD*,
shoelace_data shoelace_data
WHERE int4ne(6, <emphasis>shoelace_data.sl_avail</emphasis>)
@@ -1222,7 +1227,7 @@ INSERT INTO shoelace_log VALUES(
<ProgramListing>
INSERT INTO shoelace_log VALUES(
shoelace_data.sl_name, 6,
- current_user, current_timestamp
+ current_user, current_timestamp)
FROM shoelace_data
WHERE 6 != shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';
@@ -1317,18 +1322,6 @@ CREATE RULE shoe_del_protect AS ON DELETE TO shoe
parse trees will be empty and the whole query will become
nothing because there is nothing left to be optimized or
executed after the rule system is done with it.
-
- <Note>
- <Title>Note</Title>
- <Para>
- This way might irritate frontend applications because
- absolutely nothing happened on the database and thus, the
- backend will not return anything for the query. Not
- even a <symbol>PGRES_EMPTY_QUERY</symbol> will be available in <application>libpq</>.
- In <application>psql</application>, nothing happens. This might change in the future.
- </Para>
- </Note>
-
</Para>
<Para>
@@ -1516,7 +1509,7 @@ UPDATE shoelace_data SET
Again an update rule has been applied and so the wheel
turns on and we are in rewrite round 3. This time rule
- <literal>log_shoelace</literal> gets applied what produces the extra
+ <literal>log_shoelace</literal> gets applied, producing the extra
parse tree
<ProgramListing>
@@ -1648,7 +1641,7 @@ sl9 | 0|pink | 35|inch | 88.9
sl10 | 1000|magenta | 40|inch | 101.6
</ProgramListing>
- For the 1000 magenta shoelaces we must debt Al before we can
+ For the 1000 magenta shoelaces we must debit Al before we can
throw 'em away, but that's another problem. The pink entry we delete.
To make it a little harder for <ProductName>PostgreSQL</ProductName>,
we don't delete it directly. Instead we create one more view
@@ -1799,6 +1792,56 @@ GRANT SELECT ON phone_number TO secretary;
</Para>
</Sect1>
+<Sect1 id="rules-status">
+<Title>Rules and Command Status</Title>
+
+<Para>
+ The <ProductName>PostgreSQL</ProductName> server returns a command
+ status string, such as <literal>INSERT 149592 1</>, for each
+ query it receives. This is simple enough when there are no rules
+ involved, but what happens when the query is rewritten by rules?
+</Para>
+
+<Para>
+ As of <ProductName>PostgreSQL</ProductName> 7.3, rules affect the
+ command status as follows:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If there is no unconditional INSTEAD rule for the query, then
+ the originally given query will be executed, and its command
+ status will be returned as usual. (But note that if there were
+ any conditional INSTEAD rules, the negation of their qualifications
+ will have been added to the original query. This may reduce the
+ number of rows it processes, and if so the reported status will
+ be affected.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If there is any unconditional INSTEAD rule for the query, then
+ the original query will not be executed at all. In this case,
+ the server will return the command status for the last query that
+ was inserted by an INSTEAD rule (conditional or unconditional)
+ and is of the same type (INSERT, UPDATE, or DELETE) as the original
+ query. If no query meeting those requirements is added by any
+ rule, then the returned command status shows the original query
+ type and zeroes for the tuple-count and OID fields.
+ </para>
+ </listitem>
+ </orderedlist>
+</Para>
+
+<Para>
+ The programmer can ensure that any desired INSTEAD rule is the one
+ that sets the command status in the second case, by giving it the
+ alphabetically last rule name among the active rules, so that it
+ fires last.
+</Para>
+</Sect1>
+
<Sect1 id="rules-triggers">
<Title>Rules versus Triggers</Title>