aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_relation.c12
-rw-r--r--src/test/regress/expected/alter_table.out85
-rw-r--r--src/test/regress/sql/alter_table.sql20
3 files changed, 116 insertions, 1 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index d945638fcbf..ea62cbb41a6 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1828,9 +1828,19 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
varattno++;
Assert(varattno == te->resno);
+ /*
+ * In scenarios where columns have been added to a view
+ * since the outer query was originally parsed, there can
+ * be more items in the subquery tlist than the outer
+ * query expects. We should ignore such extra column(s)
+ * --- compare the behavior for composite-returning
+ * functions, in the RTE_FUNCTION case below.
+ */
+ if (!aliasp_item)
+ break;
+
if (colnames)
{
- /* Assume there is one alias per target item */
char *label = strVal(lfirst(aliasp_item));
*colnames = lappend(*colnames, makeString(pstrdup(label)));
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 6eab5d6e022..6364eb8c332 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -2099,6 +2099,91 @@ Foreign-key constraints:
"check_fk_presence_2_id_fkey" FOREIGN KEY (id) REFERENCES check_fk_presence_1(id)
DROP TABLE check_fk_presence_1, check_fk_presence_2;
+-- check column addition within a view (bug #14876)
+create table at_base_table(id int, stuff text);
+insert into at_base_table values (23, 'skidoo');
+create view at_view_1 as select * from at_base_table bt;
+create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1;
+\d+ at_view_1
+ View "public.at_view_1"
+ Column | Type | Modifiers | Storage | Description
+--------+---------+-----------+----------+-------------
+ id | integer | | plain |
+ stuff | text | | extended |
+View definition:
+ SELECT bt.id,
+ bt.stuff
+ FROM at_base_table bt;
+
+\d+ at_view_2
+ View "public.at_view_2"
+ Column | Type | Modifiers | Storage | Description
+--------+---------+-----------+----------+-------------
+ id | integer | | plain |
+ stuff | text | | extended |
+ j | json | | extended |
+View definition:
+ SELECT v1.id,
+ v1.stuff,
+ to_json(v1.*) AS j
+ FROM at_view_1 v1;
+
+explain (verbose, costs off) select * from at_view_2;
+ QUERY PLAN
+----------------------------------------------------------
+ Seq Scan on public.at_base_table bt
+ Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff))
+(2 rows)
+
+select * from at_view_2;
+ id | stuff | j
+----+--------+----------------------------
+ 23 | skidoo | {"id":23,"stuff":"skidoo"}
+(1 row)
+
+create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt;
+\d+ at_view_1
+ View "public.at_view_1"
+ Column | Type | Modifiers | Storage | Description
+--------+---------+-----------+----------+-------------
+ id | integer | | plain |
+ stuff | text | | extended |
+ more | integer | | plain |
+View definition:
+ SELECT bt.id,
+ bt.stuff,
+ 2 + 2 AS more
+ FROM at_base_table bt;
+
+\d+ at_view_2
+ View "public.at_view_2"
+ Column | Type | Modifiers | Storage | Description
+--------+---------+-----------+----------+-------------
+ id | integer | | plain |
+ stuff | text | | extended |
+ j | json | | extended |
+View definition:
+ SELECT v1.id,
+ v1.stuff,
+ to_json(v1.*) AS j
+ FROM at_view_1 v1;
+
+explain (verbose, costs off) select * from at_view_2;
+ QUERY PLAN
+----------------------------------------------------------------
+ Seq Scan on public.at_base_table bt
+ Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff, NULL))
+(2 rows)
+
+select * from at_view_2;
+ id | stuff | j
+----+--------+----------------------------------------
+ 23 | skidoo | {"id":23,"stuff":"skidoo","more":null}
+(1 row)
+
+drop view at_view_2;
+drop view at_view_1;
+drop table at_base_table;
--
-- lock levels
--
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index f1004b5a395..7e29b4855c2 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -1365,6 +1365,26 @@ ROLLBACK;
\d check_fk_presence_2
DROP TABLE check_fk_presence_1, check_fk_presence_2;
+-- check column addition within a view (bug #14876)
+create table at_base_table(id int, stuff text);
+insert into at_base_table values (23, 'skidoo');
+create view at_view_1 as select * from at_base_table bt;
+create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1;
+\d+ at_view_1
+\d+ at_view_2
+explain (verbose, costs off) select * from at_view_2;
+select * from at_view_2;
+
+create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt;
+\d+ at_view_1
+\d+ at_view_2
+explain (verbose, costs off) select * from at_view_2;
+select * from at_view_2;
+
+drop view at_view_2;
+drop view at_view_1;
+drop table at_base_table;
+
--
-- lock levels
--