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.
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)
{
var = make_var(pstate, rte, attnum, location);
/* Require read access to the column */
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);
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
--