Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1402201

Browse files
committed
Clean up checking of relkind for ALTER TABLE and LOCK TABLE commands.
Disallow cases like adding constraints to sequences :-(, and eliminate now-unnecessary search of pg_rewrite to decide if a relation is a view.
1 parent deb21f0 commit 1402201

File tree

1 file changed

+39
-91
lines changed

1 file changed

+39
-91
lines changed

src/backend/commands/command.c

Lines changed: 39 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.114 2000/12/22 23:12:05 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.115 2001/01/07 00:05:22 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -57,8 +57,7 @@
5757

5858

5959
static bool needs_toast_table(Relation rel);
60-
static bool is_viewr(char *relname);
61-
static bool is_view(Relation rel);
60+
static bool is_relation(char *name);
6261

6362

6463
/* --------------------------------
@@ -302,6 +301,11 @@ AlterTableAddColumn(const char *relationName,
302301
* release until end of transaction.
303302
*/
304303
rel = heap_openr(relationName, AccessExclusiveLock);
304+
305+
if (rel->rd_rel->relkind != RELKIND_RELATION)
306+
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
307+
relationName);
308+
305309
myrelid = RelationGetRelid(rel);
306310
heap_close(rel, NoLock); /* close rel but keep lock! */
307311

@@ -367,13 +371,6 @@ AlterTableAddColumn(const char *relationName,
367371
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
368372
relationName);
369373

370-
/*
371-
* XXX is the following check sufficient?
372-
*/
373-
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
374-
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
375-
relationName);
376-
377374
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
378375
maxatts = minattnum + 1;
379376
if (maxatts > MaxHeapAttributeNumber)
@@ -517,8 +514,9 @@ AlterTableAlterColumn(const char *relationName,
517514
#endif
518515

519516
rel = heap_openr(relationName, AccessExclusiveLock);
520-
if ( rel->rd_rel->relkind == RELKIND_VIEW )
521-
elog(ERROR, "ALTER TABLE: %s is a view", relationName);
517+
if (rel->rd_rel->relkind != RELKIND_RELATION)
518+
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
519+
relationName);
522520
myrelid = RelationGetRelid(rel);
523521
heap_close(rel, NoLock);
524522

@@ -936,6 +934,11 @@ AlterTableDropColumn(const char *relationName,
936934
* release until end of transaction.
937935
*/
938936
rel = heap_openr(relationName, AccessExclusiveLock);
937+
938+
if (rel->rd_rel->relkind != RELKIND_RELATION)
939+
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
940+
relationName);
941+
939942
myrelid = RelationGetRelid(rel);
940943
heap_close(rel, NoLock); /* close rel but keep lock! */
941944

@@ -969,15 +972,6 @@ AlterTableDropColumn(const char *relationName,
969972
reltup = heap_copytuple(&classtuple);
970973
ReleaseBuffer(buffer);
971974

972-
/*
973-
* XXX is the following check sufficient?
974-
*/
975-
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
976-
{
977-
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
978-
relationName);
979-
}
980-
981975
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
982976

983977
/*
@@ -1090,9 +1084,10 @@ AlterTableAddConstraint(char *relationName,
10901084
elog(ERROR, "ALTER TABLE: permission denied");
10911085
#endif
10921086

1093-
/* check to see if the table to be constrained is a view. */
1094-
if (is_viewr(relationName))
1095-
elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
1087+
/* Disallow ADD CONSTRAINT on views, indexes, sequences, etc */
1088+
if (! is_relation(relationName))
1089+
elog(ERROR, "ALTER TABLE ADD CONSTRAINT: %s is not a table",
1090+
relationName);
10961091

10971092
switch (nodeTag(newConstraint))
10981093
{
@@ -1482,9 +1477,18 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
14821477
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
14831478
relationName);
14841479

1485-
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION)
1486-
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
1487-
relationName);
1480+
switch (((Form_pg_class) GETSTRUCT(tuple))->relkind)
1481+
{
1482+
case RELKIND_RELATION:
1483+
case RELKIND_INDEX:
1484+
case RELKIND_VIEW:
1485+
case RELKIND_SEQUENCE:
1486+
/* ok to change owner */
1487+
break;
1488+
default:
1489+
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence",
1490+
relationName);
1491+
}
14881492

14891493
/*
14901494
* modify the table's entry and write to the heap
@@ -1541,6 +1545,11 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
15411545
* release until end of transaction.
15421546
*/
15431547
rel = heap_openr(relationName, AccessExclusiveLock);
1548+
1549+
if (rel->rd_rel->relkind != RELKIND_RELATION)
1550+
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
1551+
relationName);
1552+
15441553
myrelid = RelationGetRelid(rel);
15451554

15461555
/*
@@ -1569,19 +1578,8 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
15691578
ReleaseBuffer(buffer);
15701579

15711580
/*
1572-
* XXX is the following check sufficient? At least it would
1573-
* allow to create TOAST tables for views. But why not - someone
1574-
* can insert into a view, so it shouldn't be impossible to hide
1575-
* huge data there :-)
1576-
*
1577-
* Not any more.
1581+
* Is it already toasted?
15781582
*/
1579-
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
1580-
{
1581-
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
1582-
relationName);
1583-
}
1584-
15851583
if (((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid != InvalidOid)
15861584
{
15871585
if (silent)
@@ -1781,9 +1779,6 @@ LockTableCommand(LockStmt *lockstmt)
17811779
if (rel->rd_rel->relkind != RELKIND_RELATION)
17821780
elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname);
17831781

1784-
if (is_view(rel))
1785-
elog(ERROR, "LOCK TABLE: cannot lock a view");
1786-
17871782
if (lockstmt->mode == AccessShareLock)
17881783
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_RD);
17891784
else
@@ -1799,60 +1794,13 @@ LockTableCommand(LockStmt *lockstmt)
17991794

18001795

18011796
static bool
1802-
is_viewr(char *name)
1797+
is_relation(char *name)
18031798
{
18041799
Relation rel = heap_openr(name, NoLock);
18051800

1806-
bool retval = is_view(rel);
1801+
bool retval = (rel->rd_rel->relkind == RELKIND_RELATION);
18071802

18081803
heap_close(rel, NoLock);
18091804

18101805
return retval;
18111806
}
1812-
1813-
static bool
1814-
is_view(Relation rel)
1815-
{
1816-
Relation RewriteRelation;
1817-
HeapScanDesc scanDesc;
1818-
ScanKeyData scanKeyData;
1819-
HeapTuple tuple;
1820-
Form_pg_rewrite data;
1821-
bool retval = false;
1822-
1823-
/*
1824-
* Open the pg_rewrite relation.
1825-
*/
1826-
RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
1827-
1828-
/*
1829-
* Scan the RuleRelation ('pg_rewrite') for all the tuples that has
1830-
* the same ev_class as the relation being checked.
1831-
*/
1832-
ScanKeyEntryInitialize(&scanKeyData,
1833-
0,
1834-
Anum_pg_rewrite_ev_class,
1835-
F_OIDEQ,
1836-
ObjectIdGetDatum(rel->rd_id));
1837-
scanDesc = heap_beginscan(RewriteRelation,
1838-
0, SnapshotNow, 1, &scanKeyData);
1839-
1840-
while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
1841-
{
1842-
if (tuple->t_data != NULL)
1843-
{
1844-
data = (Form_pg_rewrite) GETSTRUCT(tuple);
1845-
if (data->ev_type == '1')
1846-
{
1847-
retval = true;
1848-
break;
1849-
}
1850-
}
1851-
1852-
}
1853-
1854-
heap_endscan(scanDesc);
1855-
heap_close(RewriteRelation, RowExclusiveLock);
1856-
1857-
return retval;
1858-
}

0 commit comments

Comments
 (0)