aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-10-24 14:53:58 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-10-24 14:53:58 -0400
commitf01936f70b58dec8136399f6258b37d762c3cec3 (patch)
treebac87c2d87150a613095d69764761a1b10dbe6e7 /src
parentd01a7442190686a981c0a5ce330e962d8083ac4f (diff)
downloadpostgresql-f01936f70b58dec8136399f6258b37d762c3cec3.tar.gz
postgresql-f01936f70b58dec8136399f6258b37d762c3cec3.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_relation.c11
-rw-r--r--src/test/regress/expected/rules.out22
-rw-r--r--src/test/regress/sql/rules.sql15
3 files changed, 46 insertions, 2 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 5359e691dd1..a97db6bfa8f 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -501,10 +501,17 @@ 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 (SearchSysCacheExists2(ATTNUM,
ObjectIdGetDatum(rte->relid),
- Int16GetDatum(attnum)))
+ Int16GetDatum(attnum)) &&
+ get_rel_relkind(rte->relid) != RELKIND_VIEW)
{
var = make_var(pstate, rte, attnum, location);
/* Require read access to the column */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 20cdc39752d..53a4b2cfb93 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1459,6 +1459,28 @@ ERROR: cannot drop rule _RETURN on view fooview because view fooview requires i
HINT: You can drop view fooview instead.
drop view fooview;
--
+-- 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 16dc106ab07..5ec8bbb63fa 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -860,6 +860,21 @@ drop rule "_RETURN" on fooview;
drop view fooview;
--
+-- 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
--