aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/view.c20
-rw-r--r--src/test/regress/expected/create_view.out34
-rw-r--r--src/test/regress/sql/create_view.sql25
3 files changed, 56 insertions, 23 deletions
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index e183ab097c4..459e9821d08 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -282,7 +282,12 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
NameStr(oldattr->attname),
NameStr(newattr->attname)),
errhint("Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead.")));
- /* XXX would it be safe to allow atttypmod to change? Not sure */
+
+ /*
+ * We cannot allow type, typmod, or collation to change, since these
+ * properties may be embedded in Vars of other views/rules referencing
+ * this one. Other column attributes can be ignored.
+ */
if (newattr->atttypid != oldattr->atttypid ||
newattr->atttypmod != oldattr->atttypmod)
ereport(ERROR,
@@ -293,7 +298,18 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
oldattr->atttypmod),
format_type_with_typemod(newattr->atttypid,
newattr->atttypmod))));
- /* We can ignore the remaining attributes of an attribute... */
+
+ /*
+ * At this point, attcollations should be both valid or both invalid,
+ * so applying get_collation_name unconditionally should be fine.
+ */
+ if (newattr->attcollation != oldattr->attcollation)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("cannot change collation of view column \"%s\" from \"%s\" to \"%s\"",
+ NameStr(oldattr->attname),
+ get_collation_name(oldattr->attcollation),
+ get_collation_name(newattr->attcollation))));
}
/*
diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out
index ca1833dc66d..ae7c04353cf 100644
--- a/src/test/regress/expected/create_view.out
+++ b/src/test/regress/expected/create_view.out
@@ -54,27 +54,27 @@ CREATE VIEW key_dependent_view_no_cols AS
--
-- CREATE OR REPLACE VIEW
--
-CREATE TABLE viewtest_tbl (a int, b int);
+CREATE TABLE viewtest_tbl (a int, b int, c numeric(10,1), d text COLLATE "C");
COPY viewtest_tbl FROM stdin;
CREATE OR REPLACE VIEW viewtest AS
SELECT * FROM viewtest_tbl;
CREATE OR REPLACE VIEW viewtest AS
SELECT * FROM viewtest_tbl WHERE a > 10;
SELECT * FROM viewtest;
- a | b
-----+----
- 15 | 20
- 20 | 25
+ a | b | c | d
+----+----+-----+-------
+ 15 | 20 | 3.3 | xyzz
+ 20 | 25 | 4.4 | xyzzy
(2 rows)
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC;
+ SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC;
SELECT * FROM viewtest;
- a | b
-----+----
- 20 | 25
- 15 | 20
- 10 | 15
+ a | b | c | d
+----+----+-----+-------
+ 20 | 25 | 4.4 | xyzzy
+ 15 | 20 | 3.3 | xyzz
+ 10 | 15 | 2.2 | xyz
(3 rows)
-- should fail
@@ -88,11 +88,19 @@ ERROR: cannot change name of view column "a" to "?column?"
HINT: Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead.
-- should fail
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b::numeric FROM viewtest_tbl;
+ SELECT a, b::numeric, c, d FROM viewtest_tbl;
ERROR: cannot change data type of view column "b" from integer to numeric
+-- should fail
+CREATE OR REPLACE VIEW viewtest AS
+ SELECT a, b, c::numeric(10,2), d FROM viewtest_tbl;
+ERROR: cannot change data type of view column "c" from numeric(10,1) to numeric(10,2)
+-- should fail
+CREATE OR REPLACE VIEW viewtest AS
+ SELECT a, b, c, d COLLATE "POSIX" FROM viewtest_tbl;
+ERROR: cannot change collation of view column "d" from "C" to "POSIX"
-- should work
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b, 0 AS c FROM viewtest_tbl;
+ SELECT a, b, c, d, 0 AS e FROM viewtest_tbl;
DROP VIEW viewtest;
DROP TABLE viewtest_tbl;
-- tests for temporary views
diff --git a/src/test/regress/sql/create_view.sql b/src/test/regress/sql/create_view.sql
index 6bb5b8df5e0..829f3ddbe68 100644
--- a/src/test/regress/sql/create_view.sql
+++ b/src/test/regress/sql/create_view.sql
@@ -67,12 +67,13 @@ CREATE VIEW key_dependent_view_no_cols AS
-- CREATE OR REPLACE VIEW
--
-CREATE TABLE viewtest_tbl (a int, b int);
+CREATE TABLE viewtest_tbl (a int, b int, c numeric(10,1), d text COLLATE "C");
+
COPY viewtest_tbl FROM stdin;
-5 10
-10 15
-15 20
-20 25
+5 10 1.1 xy
+10 15 2.2 xyz
+15 20 3.3 xyzz
+20 25 4.4 xyzzy
\.
CREATE OR REPLACE VIEW viewtest AS
@@ -84,7 +85,7 @@ CREATE OR REPLACE VIEW viewtest AS
SELECT * FROM viewtest;
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC;
+ SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC;
SELECT * FROM viewtest;
@@ -98,11 +99,19 @@ CREATE OR REPLACE VIEW viewtest AS
-- should fail
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b::numeric FROM viewtest_tbl;
+ SELECT a, b::numeric, c, d FROM viewtest_tbl;
+
+-- should fail
+CREATE OR REPLACE VIEW viewtest AS
+ SELECT a, b, c::numeric(10,2), d FROM viewtest_tbl;
+
+-- should fail
+CREATE OR REPLACE VIEW viewtest AS
+ SELECT a, b, c, d COLLATE "POSIX" FROM viewtest_tbl;
-- should work
CREATE OR REPLACE VIEW viewtest AS
- SELECT a, b, 0 AS c FROM viewtest_tbl;
+ SELECT a, b, c, d, 0 AS e FROM viewtest_tbl;
DROP VIEW viewtest;
DROP TABLE viewtest_tbl;