Skip to content

Commit 2383d6d

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 613a9ed commit 2383d6d

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
@@ -383,11 +383,18 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
383383
attnum = specialAttNum(colname);
384384
if (attnum != InvalidAttrNumber)
385385
{
386-
/* now check to see if column actually is defined */
386+
/*
387+
* Now check to see if column actually is defined. Because of
388+
* an ancient oversight in DefineQueryRewrite, it's possible that
389+
* pg_attribute contains entries for system columns for a view,
390+
* even though views should not have such --- so we also check
391+
* the relkind. This kluge will not be needed in 9.3 and later.
392+
*/
387393
if (SearchSysCacheExists(ATTNUM,
388394
ObjectIdGetDatum(rte->relid),
389395
Int16GetDatum(attnum),
390-
0, 0))
396+
0, 0) &&
397+
get_rel_relkind(rte->relid) != RELKIND_VIEW)
391398
{
392399
result = (Node *) make_var(pstate, rte, attnum);
393400
/* Require read access */

src/test/regress/expected/rules.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,28 @@ insert into rule_and_refint_t3 values (1, 13, 11, 'row8');
14421442
ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey"
14431443
DETAIL: Key (id3a,id3b)=(1,13) is not present in table "rule_and_refint_t1".
14441444
--
1445+
-- test conversion of table to view (needed to load some pg_dump files)
1446+
--
1447+
create table fooview (x int, y text);
1448+
select xmin, * from fooview;
1449+
xmin | x | y
1450+
------+---+---
1451+
(0 rows)
1452+
1453+
create rule "_RETURN" as on select to fooview do instead
1454+
select 1 as x, 'aaa'::text as y;
1455+
select * from fooview;
1456+
x | y
1457+
---+-----
1458+
1 | aaa
1459+
(1 row)
1460+
1461+
select xmin, * from fooview; -- fail, views don't have such a column
1462+
ERROR: column "xmin" does not exist
1463+
LINE 1: select xmin, * from fooview;
1464+
^
1465+
drop view fooview;
1466+
--
14451467
-- check for planner problems with complex inherited UPDATES
14461468
--
14471469
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
@@ -851,6 +851,21 @@ create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3
851851
insert into rule_and_refint_t3 values (1, 11, 13, 'row7');
852852
insert into rule_and_refint_t3 values (1, 13, 11, 'row8');
853853

854+
--
855+
-- test conversion of table to view (needed to load some pg_dump files)
856+
--
857+
858+
create table fooview (x int, y text);
859+
select xmin, * from fooview;
860+
861+
create rule "_RETURN" as on select to fooview do instead
862+
select 1 as x, 'aaa'::text as y;
863+
864+
select * from fooview;
865+
select xmin, * from fooview; -- fail, views don't have such a column
866+
867+
drop view fooview;
868+
854869
--
855870
-- check for planner problems with complex inherited UPDATES
856871
--

0 commit comments

Comments
 (0)