1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

When converting a table to a view, remove its 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.

Patch in HEAD only.  This bug has been there forever, but in the back
branches we will have to defend against existing mis-converted views,
so it doesn't seem worthwhile to change the conversion code too.
This commit is contained in:
Tom Lane
2012-10-24 13:39:37 -04:00
parent f4c4335a4a
commit a4e8680a6c
5 changed files with 88 additions and 2 deletions

View File

@ -1434,6 +1434,47 @@ DeleteAttributeTuples(Oid relid)
heap_close(attrel, RowExclusiveLock);
}
/*
* DeleteSystemAttributeTuples
*
* Remove pg_attribute rows for system columns of the given relid.
*
* Note: this is only used when converting a table to a view. Views don't
* have system columns, so we should remove them from pg_attribute.
*/
void
DeleteSystemAttributeTuples(Oid relid)
{
Relation attrel;
SysScanDesc scan;
ScanKeyData key[2];
HeapTuple atttup;
/* Grab an appropriate lock on the pg_attribute relation */
attrel = heap_open(AttributeRelationId, RowExclusiveLock);
/* Use the index to scan only system attributes of the target relation */
ScanKeyInit(&key[0],
Anum_pg_attribute_attrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relid));
ScanKeyInit(&key[1],
Anum_pg_attribute_attnum,
BTLessEqualStrategyNumber, F_INT2LE,
Int16GetDatum(0));
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
SnapshotNow, 2, key);
/* Delete all the matching tuples */
while ((atttup = systable_getnext(scan)) != NULL)
simple_heap_delete(attrel, &atttup->t_self);
/* Clean up after the scan */
systable_endscan(scan);
heap_close(attrel, RowExclusiveLock);
}
/*
* RemoveAttributeById
*

View File

@ -18,6 +18,7 @@
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
@ -510,13 +511,19 @@ DefineQueryRewrite(char *rulename,
}
/*
* IF the relation is becoming a view, delete the storage files associated
* with it. NB: we had better have AccessExclusiveLock to do this ...
* If the relation is becoming a view, delete the storage files associated
* with it. Also, get rid of any system attribute entries in pg_attribute,
* because a view shouldn't have any of those.
*
* NB: we had better have AccessExclusiveLock to do this ...
*
* XXX what about getting rid of its TOAST table? For now, we don't.
*/
if (RelisBecomingView)
{
RelationDropStorage(event_relation);
DeleteSystemAttributeTuples(event_relid);
}
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);