From: Tom Lane Date: Wed, 24 Oct 2012 18:54:17 +0000 (-0400) Subject: Prevent parser from believing that views have system columns. X-Git-Tag: REL8_3_22~20 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=2383d6d132ea1908af73f1285c27f22bc8b6065f;p=postgresql.git 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. --- diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 444934efa4d..af02202d958 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -383,11 +383,18 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname, attnum = specialAttNum(colname); if (attnum != InvalidAttrNumber) { - /* now check to see if column actually is defined */ + /* + * Now check to see if column actually is defined. Because of + * an ancient oversight in DefineQueryRewrite, it's possible that + * pg_attribute contains entries for system columns for a view, + * even though views should not have such --- so we also check + * the relkind. This kluge will not be needed in 9.3 and later. + */ if (SearchSysCacheExists(ATTNUM, ObjectIdGetDatum(rte->relid), Int16GetDatum(attnum), - 0, 0)) + 0, 0) && + get_rel_relkind(rte->relid) != RELKIND_VIEW) { result = (Node *) make_var(pstate, rte, attnum); /* Require read access */ diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 3439642fe65..2e5d0974dd5 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1442,6 +1442,28 @@ insert into rule_and_refint_t3 values (1, 13, 11, 'row8'); ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey" DETAIL: Key (id3a,id3b)=(1,13) is not present in table "rule_and_refint_t1". -- +-- test conversion of table to view (needed to load some pg_dump files) +-- +create table fooview (x int, y text); +select xmin, * from fooview; + xmin | x | y +------+---+--- +(0 rows) + +create rule "_RETURN" as on select to fooview do instead + select 1 as x, 'aaa'::text as y; +select * from fooview; + x | y +---+----- + 1 | aaa +(1 row) + +select xmin, * from fooview; -- fail, views don't have such a column +ERROR: column "xmin" does not exist +LINE 1: select xmin, * from fooview; + ^ +drop view fooview; +-- -- check for planner problems with complex inherited UPDATES -- create table id (id serial primary key, name text); diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index e898336d92a..428f92bf4f5 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -851,6 +851,21 @@ create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3 insert into rule_and_refint_t3 values (1, 11, 13, 'row7'); insert into rule_and_refint_t3 values (1, 13, 11, 'row8'); +-- +-- test conversion of table to view (needed to load some pg_dump files) +-- + +create table fooview (x int, y text); +select xmin, * from fooview; + +create rule "_RETURN" as on select to fooview do instead + select 1 as x, 'aaa'::text as y; + +select * from fooview; +select xmin, * from fooview; -- fail, views don't have such a column + +drop view fooview; + -- -- check for planner problems with complex inherited UPDATES --