Thanks to visit codestin.com
Credit goes to github.com

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)