Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9619fdc

Browse files
committed
Prevent parser from believing that views have system columns.
Views should not have any pg_attribute entries for system columns. However, we forgot to remove such entries when converting a table to a view. This could lead to crashes later on, if someone attempted to reference such a column, as reported by Kohei KaiGai. This problem is corrected properly in HEAD (by removing the pg_attribute entries during conversion), but in the back branches we need to defend against existing mis-converted views. This fix costs us an extra syscache lookup per system column reference, which is annoying but probably not really measurable in the big scheme of things.
1 parent 586250c commit 9619fdc

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/backend/parser/parse_relation.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,17 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
501501
attnum = specialAttNum(colname);
502502
if (attnum != InvalidAttrNumber)
503503
{
504-
/* now check to see if column actually is defined */
504+
/*
505+
* Now check to see if column actually is defined. Because of
506+
* an ancient oversight in DefineQueryRewrite, it's possible that
507+
* pg_attribute contains entries for system columns for a view,
508+
* even though views should not have such --- so we also check
509+
* the relkind. This kluge will not be needed in 9.3 and later.
510+
*/
505511
if (SearchSysCacheExists2(ATTNUM,
506512
ObjectIdGetDatum(rte->relid),
507-
Int16GetDatum(attnum)))
513+
Int16GetDatum(attnum)) &&
514+
get_rel_relkind(rte->relid) != RELKIND_VIEW)
508515
{
509516
var = make_var(pstate, rte, attnum, location);
510517
/* Require read access to the column */

src/test/regress/expected/rules.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,28 @@ ERROR: cannot drop rule _RETURN on view fooview because view fooview requires i
14521452
HINT: You can drop view fooview instead.
14531453
drop view fooview;
14541454
--
1455+
-- test conversion of table to view (needed to load some pg_dump files)
1456+
--
1457+
create table fooview (x int, y text);
1458+
select xmin, * from fooview;
1459+
xmin | x | y
1460+
------+---+---
1461+
(0 rows)
1462+
1463+
create rule "_RETURN" as on select to fooview do instead
1464+
select 1 as x, 'aaa'::text as y;
1465+
select * from fooview;
1466+
x | y
1467+
---+-----
1468+
1 | aaa
1469+
(1 row)
1470+
1471+
select xmin, * from fooview; -- fail, views don't have such a column
1472+
ERROR: column "xmin" does not exist
1473+
LINE 1: select xmin, * from fooview;
1474+
^
1475+
drop view fooview;
1476+
--
14551477
-- check for planner problems with complex inherited UPDATES
14561478
--
14571479
create table id (id serial primary key, name text);

src/test/regress/sql/rules.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,21 @@ create view fooview as select 'foo'::text;
859859
drop rule "_RETURN" on fooview;
860860
drop view fooview;
861861

862+
--
863+
-- test conversion of table to view (needed to load some pg_dump files)
864+
--
865+
866+
create table fooview (x int, y text);
867+
select xmin, * from fooview;
868+
869+
create rule "_RETURN" as on select to fooview do instead
870+
select 1 as x, 'aaa'::text as y;
871+
872+
select * from fooview;
873+
select xmin, * from fooview; -- fail, views don't have such a column
874+
875+
drop view fooview;
876+
862877
--
863878
-- check for planner problems with complex inherited UPDATES
864879
--

0 commit comments

Comments
 (0)