Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1da5c11

Browse files
committed
Improve behavior of concurrent ALTER <relation> .. SET SCHEMA.
If the referrent of a name changes while we're waiting for the lock,we must recheck permissons. We also now check the relkind beforelocking, since it's easy to do that long the way.Patch by me; review by Noah Misch.
1 parent74a1d4f commit1da5c11

File tree

2 files changed

+70
-44
lines changed

2 files changed

+70
-44
lines changed

‎src/backend/commands/alter.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
191191
caseOBJECT_TABLE:
192192
caseOBJECT_VIEW:
193193
caseOBJECT_FOREIGN_TABLE:
194-
CheckRelationOwnership(stmt->relation, true);
195194
AlterTableNamespace(stmt->relation,stmt->newschema,
196195
stmt->objectType,AccessExclusiveLock);
197196
break;

‎src/backend/commands/tablecmds.c

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9379,28 +9379,35 @@ ATExecGenericOptions(Relation rel, List *options)
93799379
heap_freetuple(tuple);
93809380
}
93819381

9382-
93839382
/*
9384-
* Execute ALTER TABLE SET SCHEMA
9385-
*
9386-
* Note: caller must have checked ownership of the relation already
9383+
* Perform permissions and integrity checks before acquiring a relation lock.
93879384
*/
9388-
void
9389-
AlterTableNamespace(RangeVar*relation,constchar*newschema,
9390-
ObjectTypestmttype,LOCKMODElockmode)
9385+
staticvoid
9386+
RangeVarCallbackForAlterTableNamespace(constRangeVar*rv,Oidrelid,
9387+
Oidoldrelid,void*arg)
93919388
{
9392-
Relationrel;
9393-
Oidrelid;
9394-
OidoldNspOid;
9395-
OidnspOid;
9396-
RelationclassRel;
9389+
HeapTupletuple;
9390+
Form_pg_classform;
9391+
ObjectTypestmttype;
9392+
9393+
tuple=SearchSysCache1(RELOID,ObjectIdGetDatum(relid));
9394+
if (!HeapTupleIsValid(tuple))
9395+
return;/* concurrently dropped */
9396+
form= (Form_pg_class)GETSTRUCT(tuple);
93979397

9398-
rel=relation_openrv(relation,lockmode);
9398+
/* Must own table. */
9399+
if (!pg_class_ownercheck(relid,GetUserId()))
9400+
aclcheck_error(ACLCHECK_NOT_OWNER,ACL_KIND_CLASS,rv->relname);
93999401

9400-
relid=RelationGetRelid(rel);
9401-
oldNspOid=RelationGetNamespace(rel);
9402+
/* No system table modifications unless explicitly allowed. */
9403+
if (!allowSystemTableMods&&IsSystemClass(form))
9404+
ereport(ERROR,
9405+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
9406+
errmsg("permission denied: \"%s\" is a system catalog",
9407+
rv->relname)));
94029408

94039409
/* Check relation type against type specified in the ALTER command */
9410+
stmttype=* (ObjectType*)arg;
94049411
switch (stmttype)
94059412
{
94069413
caseOBJECT_TABLE:
@@ -9412,61 +9419,43 @@ AlterTableNamespace(RangeVar *relation, const char *newschema,
94129419
break;
94139420

94149421
caseOBJECT_SEQUENCE:
9415-
if (rel->rd_rel->relkind!=RELKIND_SEQUENCE)
9422+
if (form->relkind!=RELKIND_SEQUENCE)
94169423
ereport(ERROR,
94179424
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
9418-
errmsg("\"%s\" is not a sequence",
9419-
RelationGetRelationName(rel))));
9425+
errmsg("\"%s\" is not a sequence",rv->relname)));
94209426
break;
94219427

94229428
caseOBJECT_VIEW:
9423-
if (rel->rd_rel->relkind!=RELKIND_VIEW)
9429+
if (form->relkind!=RELKIND_VIEW)
94249430
ereport(ERROR,
94259431
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
9426-
errmsg("\"%s\" is not a view",
9427-
RelationGetRelationName(rel))));
9432+
errmsg("\"%s\" is not a view",rv->relname)));
94289433
break;
94299434

94309435
caseOBJECT_FOREIGN_TABLE:
9431-
if (rel->rd_rel->relkind!=RELKIND_FOREIGN_TABLE)
9436+
if (form->relkind!=RELKIND_FOREIGN_TABLE)
94329437
ereport(ERROR,
94339438
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
9434-
errmsg("\"%s\" is not a foreign table",
9435-
RelationGetRelationName(rel))));
9439+
errmsg("\"%s\" is not a foreign table",rv->relname)));
94369440
break;
94379441

94389442
default:
94399443
elog(ERROR,"unrecognized object type: %d", (int)stmttype);
94409444
}
94419445

94429446
/* Can we change the schema of this tuple? */
9443-
switch (rel->rd_rel->relkind)
9447+
switch (form->relkind)
94449448
{
94459449
caseRELKIND_RELATION:
94469450
caseRELKIND_VIEW:
9451+
caseRELKIND_SEQUENCE:
94479452
caseRELKIND_FOREIGN_TABLE:
94489453
/* ok to change schema */
94499454
break;
9450-
caseRELKIND_SEQUENCE:
9451-
{
9452-
/* if it's an owned sequence, disallow moving it by itself */
9453-
OidtableId;
9454-
int32colId;
9455-
9456-
if (sequenceIsOwned(relid,&tableId,&colId))
9457-
ereport(ERROR,
9458-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
9459-
errmsg("cannot move an owned sequence into another schema"),
9460-
errdetail("Sequence \"%s\" is linked to table \"%s\".",
9461-
RelationGetRelationName(rel),
9462-
get_rel_name(tableId))));
9463-
}
9464-
break;
94659455
caseRELKIND_COMPOSITE_TYPE:
94669456
ereport(ERROR,
94679457
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
9468-
errmsg("\"%s\" is a composite type",
9469-
RelationGetRelationName(rel)),
9458+
errmsg("\"%s\" is a composite type",rv->relname),
94709459
errhint("Use ALTER TYPE instead.")));
94719460
break;
94729461
caseRELKIND_INDEX:
@@ -9476,7 +9465,45 @@ AlterTableNamespace(RangeVar *relation, const char *newschema,
94769465
ereport(ERROR,
94779466
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
94789467
errmsg("\"%s\" is not a table, view, sequence, or foreign table",
9479-
RelationGetRelationName(rel))));
9468+
rv->relname)));
9469+
}
9470+
9471+
ReleaseSysCache(tuple);
9472+
}
9473+
9474+
/*
9475+
* Execute ALTER TABLE SET SCHEMA
9476+
*/
9477+
void
9478+
AlterTableNamespace(RangeVar*relation,constchar*newschema,
9479+
ObjectTypestmttype,LOCKMODElockmode)
9480+
{
9481+
Relationrel;
9482+
Oidrelid;
9483+
OidoldNspOid;
9484+
OidnspOid;
9485+
RelationclassRel;
9486+
9487+
relid=RangeVarGetRelidExtended(relation,lockmode, false, false,
9488+
RangeVarCallbackForAlterTableNamespace,
9489+
(void*)&stmttype);
9490+
rel=relation_open(relid,NoLock);
9491+
9492+
oldNspOid=RelationGetNamespace(rel);
9493+
9494+
/* If it's an owned sequence, disallow moving it by itself. */
9495+
if (rel->rd_rel->relkind==RELKIND_SEQUENCE)
9496+
{
9497+
OidtableId;
9498+
int32colId;
9499+
9500+
if (sequenceIsOwned(relid,&tableId,&colId))
9501+
ereport(ERROR,
9502+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
9503+
errmsg("cannot move an owned sequence into another schema"),
9504+
errdetail("Sequence \"%s\" is linked to table \"%s\".",
9505+
RelationGetRelationName(rel),
9506+
get_rel_name(tableId))));
94809507
}
94819508

94829509
/* get schema OID and check its permissions */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp