Allow ALTER VIEW command to rename the column in the view.
authorFujii Masao
Thu, 21 Nov 2019 10:55:13 +0000 (19:55 +0900)
committerFujii Masao
Thu, 21 Nov 2019 10:55:13 +0000 (19:55 +0900)
ALTER TABLE RENAME COLUMN command always can be used to rename the column
in the view, but it's reasonable to add that syntax to ALTER VIEW too.

Author: Fujii Masao
Reviewed-by: Ibrar Ahmed, Yu Kimura
Discussion: https://postgr.es/m/CAHGQGwHoQMD3b-MqTLcp1MgdhCpOKU7QNRwjFooT4_d+ti5v6g@mail.gmail.com

doc/src/sgml/ref/alter_view.sgml
src/backend/commands/view.c
src/backend/parser/gram.y
src/bin/psql/tab-complete.c
src/test/regress/expected/create_view.out
src/test/regress/sql/create_view.sql

index 2e9edc1975833c997d3ad7be3e3bb6b3439cc983..b66160bfb8955ffe0060a02eaa55b75a01e377e5 100644 (file)
@@ -24,6 +24,7 @@ PostgreSQL documentation
 ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name SET DEFAULT expression
 ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name DROP DEFAULT
 ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
+ALTER VIEW [ IF EXISTS ] name RENAME [ COLUMN ] column_name TO new_column_name
 ALTER VIEW [ IF EXISTS ] name RENAME TO new_name
 ALTER VIEW [ IF EXISTS ] name SET SCHEMA new_schema
 ALTER VIEW [ IF EXISTS ] name SET ( view_option_name [= view_option_value] [, ... ] )
@@ -65,6 +66,24 @@ ALTER VIEW [ IF EXISTS ] name RESET
     
    
 
+   
+    column_name
+    
+     
+      Name of an existing column.
+     
+    
+   
+
+   
+    new_column_name
+    
+     
+      New name for an existing column.
+     
+    
+   
+
    
     IF EXISTS
     
index 9fa433a975405a88563dcbd4c92ca0a6c2c5d28d..9b5148093b6e84ee894c32131596093078bfb81a 100644 (file)
@@ -276,7 +276,8 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
                    (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                     errmsg("cannot change name of view column \"%s\" to \"%s\"",
                            NameStr(oldattr->attname),
-                           NameStr(newattr->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 */
        if (newattr->atttypid != oldattr->atttypid ||
            newattr->atttypmod != oldattr->atttypmod)
index 2f7bd662e8a8a91d80165252ba6d07fbc13ddc0e..c5086846decc0b90e346df917386dff0b306c585 100644 (file)
@@ -8777,6 +8777,28 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
                    n->missing_ok = true;
                    $$ = (Node *)n;
                }
+           | ALTER VIEW qualified_name RENAME opt_column name TO name
+               {
+                   RenameStmt *n = makeNode(RenameStmt);
+                   n->renameType = OBJECT_COLUMN;
+                   n->relationType = OBJECT_VIEW;
+                   n->relation = $3;
+                   n->subname = $6;
+                   n->newname = $8;
+                   n->missing_ok = false;
+                   $$ = (Node *)n;
+               }
+           | ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name
+               {
+                   RenameStmt *n = makeNode(RenameStmt);
+                   n->renameType = OBJECT_COLUMN;
+                   n->relationType = OBJECT_VIEW;
+                   n->relation = $5;
+                   n->subname = $8;
+                   n->newname = $10;
+                   n->missing_ok = true;
+                   $$ = (Node *)n;
+               }
            | ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name
                {
                    RenameStmt *n = makeNode(RenameStmt);
index 1578568a91cf96ab10d448d82e1801ca4d6d2034..172e00b46ef3f3167bc2503f7c6471b96cec78d0 100644 (file)
@@ -1797,8 +1797,20 @@ psql_completion(const char *text, int start, int end)
        COMPLETE_WITH("TO");
    /* ALTER VIEW  */
    else if (Matches("ALTER", "VIEW", MatchAny))
-       COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
+       COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME",
                      "SET SCHEMA");
+   /* ALTER VIEW xxx RENAME */
+   else if (Matches("ALTER", "VIEW", MatchAny, "RENAME"))
+       COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'TO'");
+   else if (Matches("ALTER", "VIEW", MatchAny, "ALTER|RENAME", "COLUMN"))
+       COMPLETE_WITH_ATTR(prev3_wd, "");
+   /* ALTER VIEW xxx RENAME yyy */
+   else if (Matches("ALTER", "VIEW", MatchAny, "RENAME", MatchAnyExcept("TO")))
+       COMPLETE_WITH("TO");
+   /* ALTER VIEW xxx RENAME COLUMN yyy */
+   else if (Matches("ALTER", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")))
+       COMPLETE_WITH("TO");
+
    /* ALTER MATERIALIZED VIEW  */
    else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
        COMPLETE_WITH("ALTER COLUMN", "CLUSTER ON", "DEPENDS ON EXTENSION",
index 2fd36ca9a1465c17da401161c68076b478c9f773..9a92629fd79f40e5bead640d921c8e53f4f8d617 100644 (file)
@@ -64,6 +64,7 @@ ERROR:  cannot drop columns from view
 CREATE OR REPLACE VIEW viewtest AS
    SELECT 1, * FROM viewtest_tbl;
 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;
@@ -1189,6 +1190,29 @@ select pg_get_viewdef('vv1', true);
       CROSS JOIN tt6) j(aa, bb, cc_1, cc, dd);
 (1 row)
 
+create view v4 as select * from v1;
+alter view v1 rename column a to x;
+select pg_get_viewdef('v1', true);
+                  pg_get_viewdef                   
+---------------------------------------------------
+  SELECT tt2.b,                                   +
+     tt3.c,                                       +
+     tt2.a AS x,                                  +
+     tt3.ax                                       +
+    FROM tt2                                      +
+      JOIN tt3 tt3(ax, b, c, c_1, e) USING (b, c);
+(1 row)
+
+select pg_get_viewdef('v4', true);
+ pg_get_viewdef 
+----------------
+  SELECT v1.b, +
+     v1.c,     +
+     v1.x AS a,+
+     v1.ax     +
+    FROM v1;
+(1 row)
+
 -- Unnamed FULL JOIN USING is lots of fun too
 create table tt7 (x int, xx int, y int);
 alter table tt7 drop column xx;
@@ -1782,7 +1806,7 @@ drop cascades to view aliased_view_2
 drop cascades to view aliased_view_3
 drop cascades to view aliased_view_4
 DROP SCHEMA testviewschm2 CASCADE;
-NOTICE:  drop cascades to 63 other objects
+NOTICE:  drop cascades to 64 other objects
 DETAIL:  drop cascades to table t1
 drop cascades to view temporal1
 drop cascades to view temporal2
@@ -1818,6 +1842,7 @@ drop cascades to view v3
 drop cascades to table tt5
 drop cascades to table tt6
 drop cascades to view vv1
+drop cascades to view v4
 drop cascades to table tt7
 drop cascades to table tt8
 drop cascades to view vv2
index 8c0f45cc5268e846e5b99b909222fb6848ba5d57..be5d90727a9fa41e8145b53e7a6b1ef6fa404c8a 100644 (file)
@@ -391,6 +391,12 @@ select pg_get_viewdef('vv1', true);
 alter table tt5 drop column c;
 select pg_get_viewdef('vv1', true);
 
+create view v4 as select * from v1;
+alter view v1 rename column a to x;
+select pg_get_viewdef('v1', true);
+select pg_get_viewdef('v4', true);
+
+
 -- Unnamed FULL JOIN USING is lots of fun too
 
 create table tt7 (x int, xx int, y int);