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

Commit2153837

Browse files
committed
Disallow SELECT FOR UPDATE/SHARE on sequences.
We can't allow this because such an operation stores its transaction XIDinto the sequence tuple's xmax. Because VACUUM doesn't process sequences(and we don't want it to start doing so), such an xmax value won't getfrozen, meaning it will eventually refer to nonexistent pg_clog storage,and even wrap around completely. Since the row lock is ignored by nextvaland setval, the usefulness of the operation is highly debatable anyway.Per reports of trouble with pgpool 3.0, which had ill-advisedly startedusing such commands as a form of locking.In HEAD, also disallow SELECT FOR UPDATE/SHARE on toast tables. Althoughthis does work safely given the current implementation, there seems nogood reason to allow it. I refrained from changing that behavior inback branches, however.
1 parentdd2ddfb commit2153837

File tree

1 file changed

+58
-6
lines changed

1 file changed

+58
-6
lines changed

‎src/backend/executor/execMain.c

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook = NULL;
7474

7575
/* decls for local routines only used within this module */
7676
staticvoidInitPlan(QueryDesc*queryDesc,inteflags);
77+
staticvoidCheckValidRowMarkRel(Relationrel,RowMarkTypemarkType);
7778
staticvoidExecPostprocessPlan(EState*estate);
7879
staticvoidExecEndPlan(PlanState*planstate,EState*estate);
7980
staticvoidExecutePlan(EState*estate,PlanState*planstate,
@@ -837,12 +838,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
837838
break;
838839
}
839840

840-
/* if foreign table, tuples can't be locked */
841-
if (relation&&relation->rd_rel->relkind==RELKIND_FOREIGN_TABLE)
842-
ereport(ERROR,
843-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
844-
errmsg("SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"",
845-
RelationGetRelationName(relation))));
841+
/* Check that relation is a legal target for marking */
842+
if (relation)
843+
CheckValidRowMarkRel(relation,rc->markType);
846844

847845
erm= (ExecRowMark*)palloc(sizeof(ExecRowMark));
848846
erm->relation=relation;
@@ -977,6 +975,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
977975
* In most cases parser and/or planner should have noticed this already, but
978976
* let's make sure. In the view case we do need a test here, because if the
979977
* view wasn't rewritten by a rule, it had better have an INSTEAD trigger.
978+
*
979+
* Note: when changing this function, you probably also need to look at
980+
* CheckValidRowMarkRel.
980981
*/
981982
void
982983
CheckValidResultRel(RelationresultRel,CmdTypeoperation)
@@ -1047,6 +1048,57 @@ CheckValidResultRel(Relation resultRel, CmdType operation)
10471048
}
10481049
}
10491050

1051+
/*
1052+
* Check that a proposed rowmark target relation is a legal target
1053+
*
1054+
* In most cases parser and/or planner should have noticed this already, but
1055+
* they don't cover all cases.
1056+
*/
1057+
staticvoid
1058+
CheckValidRowMarkRel(Relationrel,RowMarkTypemarkType)
1059+
{
1060+
switch (rel->rd_rel->relkind)
1061+
{
1062+
caseRELKIND_RELATION:
1063+
/* OK */
1064+
break;
1065+
caseRELKIND_SEQUENCE:
1066+
/* Must disallow this because we don't vacuum sequences */
1067+
ereport(ERROR,
1068+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1069+
errmsg("cannot lock rows in sequence \"%s\"",
1070+
RelationGetRelationName(rel))));
1071+
break;
1072+
caseRELKIND_TOASTVALUE:
1073+
/* We could allow this, but there seems no good reason to */
1074+
ereport(ERROR,
1075+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1076+
errmsg("cannot lock rows in TOAST relation \"%s\"",
1077+
RelationGetRelationName(rel))));
1078+
break;
1079+
caseRELKIND_VIEW:
1080+
/* Should not get here */
1081+
ereport(ERROR,
1082+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1083+
errmsg("cannot lock rows in view \"%s\"",
1084+
RelationGetRelationName(rel))));
1085+
break;
1086+
caseRELKIND_FOREIGN_TABLE:
1087+
/* Perhaps we can support this someday, but not today */
1088+
ereport(ERROR,
1089+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1090+
errmsg("cannot lock rows in foreign table \"%s\"",
1091+
RelationGetRelationName(rel))));
1092+
break;
1093+
default:
1094+
ereport(ERROR,
1095+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1096+
errmsg("cannot lock rows in relation \"%s\"",
1097+
RelationGetRelationName(rel))));
1098+
break;
1099+
}
1100+
}
1101+
10501102
/*
10511103
* Initialize ResultRelInfo data for one result relation
10521104
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp