diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml
index 86046359b4a..998d075a645 100644
--- a/doc/src/sgml/ref/create_rule.sgml
+++ b/doc/src/sgml/ref/create_rule.sgml
@@ -1,5 +1,5 @@
@@ -21,17 +21,15 @@ PostgreSQL documentation
2001-01-05
-CREATE RULE name AS ON event
+CREATE [ OR REPLACE ] RULE name AS ON event
TO table [ WHERE condition ]
DO [ INSTEAD ] action
where action can be:
NOTHING
-|
-query
-|
-( query ; query ... )
+| query
+| ( query ; query ... )
@@ -76,9 +74,10 @@ NOTHING
condition
- Any SQL conditional expression (returning boolean). The condition expression may not
+ Any SQL conditional expression (returning boolean).
+ The condition expression may not
refer to any tables except new and
- old.
+ old, and may not contain aggregate functions.
@@ -142,6 +141,14 @@ CREATE RULE
Description
+
+ CREATE RULE defines a new rule applying to a specified
+ table or view.
+ CREATE OR REPLACE RULE will either create a
+ new rule, or replace an existing rule of the same name for the same
+ table.
+
+
The PostgreSQL
rule system allows one to define an
@@ -318,7 +325,7 @@ UPDATE mytable SET name = 'foo' WHERE id = 42;
- CREATE RULE statement is a PostgreSQL
+ CREATE RULE is a PostgreSQL
language extension.
There is no CREATE RULE statement in SQL92.
diff --git a/doc/src/sgml/ref/create_view.sgml b/doc/src/sgml/ref/create_view.sgml
index aa7c869285f..1692f9f0f77 100644
--- a/doc/src/sgml/ref/create_view.sgml
+++ b/doc/src/sgml/ref/create_view.sgml
@@ -1,5 +1,5 @@
@@ -21,7 +21,7 @@ PostgreSQL documentation
2000-03-25
-CREATE VIEW view [ ( view [ ( column name list ) ] AS SELECT query
@@ -132,13 +132,21 @@ CREATE VIEW vista AS SELECT text 'Hello World'
Description
+
- CREATE VIEW will define a view of a query.
+ CREATE VIEW defines a view of a query.
The view is not physically materialized. Instead, a query
rewrite rule (an ON SELECT> rule) is automatically generated to
support SELECT operations on views.
+
+ CREATE OR REPLACE VIEW is similar, but if a view
+ of the same name already exists, it is replaced. You can only replace
+ a view with a new query that generates the identical set of columns
+ (i.e., same column names and data types).
+
+
If a schema name is given (for example, CREATE VIEW
myschema.myview ...>) then the view is created in the
@@ -206,6 +214,7 @@ SELECT * FROM kinds;
SQL92
+
SQL92 specifies some additional capabilities for the
CREATE VIEW statement:
@@ -253,6 +262,12 @@ CREATE VIEW view [
+
+
+ CREATE OR REPLACE VIEW is a
+ PostgreSQL language extension.
+
+
diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml
index 3ba21bc1ab7..d0fc445380c 100644
--- a/doc/src/sgml/release.sgml
+++ b/doc/src/sgml/release.sgml
@@ -1,5 +1,5 @@
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
rd_att))
- elog(ERROR, "Cannot change column set of existing view %s",
- RelationGetRelationName(rel));
+ checkViewTupleDesc(descriptor, rel->rd_att);
/*
* Seems okay, so return the OID of the pre-existing view.
@@ -149,6 +146,46 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
}
}
+/*
+ * Verify that tupledesc associated with proposed new view definition
+ * matches tupledesc of old view. This is basically a cut-down version
+ * of equalTupleDescs(), with code added to generate specific complaints.
+ */
+static void
+checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
+{
+ int i;
+
+ if (newdesc->natts != olddesc->natts)
+ elog(ERROR, "Cannot change number of columns in view");
+ /* we can ignore tdhasoid */
+
+ for (i = 0; i < newdesc->natts; i++)
+ {
+ Form_pg_attribute newattr = newdesc->attrs[i];
+ Form_pg_attribute oldattr = olddesc->attrs[i];
+
+ /* XXX not right, but we don't support DROP COL on view anyway */
+ if (newattr->attisdropped != oldattr->attisdropped)
+ elog(ERROR, "Cannot change number of columns in view");
+
+ if (strcmp(NameStr(newattr->attname), NameStr(oldattr->attname)) != 0)
+ elog(ERROR, "Cannot change name of view column \"%s\"",
+ NameStr(oldattr->attname));
+ /* XXX would it be safe to allow atttypmod to change? Not sure */
+ if (newattr->atttypid != oldattr->atttypid ||
+ newattr->atttypmod != oldattr->atttypmod)
+ elog(ERROR, "Cannot change datatype of view column \"%s\"",
+ NameStr(oldattr->attname));
+ /* We can ignore the remaining attributes of an attribute... */
+ }
+ /*
+ * We ignore the constraint fields. The new view desc can't have any
+ * constraints, and the only ones that could be on the old view are
+ * defaults, which we are happy to leave in place.
+ */
+}
+
static RuleStmt *
FormViewRetrieveRule(const RangeVar *view, Query *viewParse, bool replace)
{
diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out
index ade98e6c311..e4b4d7484b6 100644
--- a/src/test/regress/expected/create_view.out
+++ b/src/test/regress/expected/create_view.out
@@ -44,14 +44,14 @@ SELECT * FROM viewtest;
-- should fail
CREATE OR REPLACE VIEW viewtest AS
SELECT a FROM viewtest_tbl WHERE a <> 20;
-ERROR: Cannot change column set of existing view viewtest
+ERROR: Cannot change number of columns in view
-- should fail
CREATE OR REPLACE VIEW viewtest AS
SELECT 1, * FROM viewtest_tbl;
-ERROR: Cannot change column set of existing view viewtest
+ERROR: Cannot change number of columns in view
-- should fail
CREATE OR REPLACE VIEW viewtest AS
SELECT a, b::numeric FROM viewtest_tbl;
-ERROR: Cannot change column set of existing view viewtest
+ERROR: Cannot change datatype of view column "b"
DROP VIEW viewtest;
DROP TABLE viewtest_tbl;