diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml index 86046359b4..998d075a64 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 aa7c869285..1692f9f0f7 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 3ba21bc1ab..d0fc445380 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 ade98e6c31..e4b4d7484b 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;