mirror of
https://github.com/postgres/postgres.git
synced 2025-07-21 16:02:15 +03:00
Create an RTE field to record the query's lock mode for each relation.
Add RangeTblEntry.rellockmode, which records the appropriate lock mode for each RTE_RELATION rangetable entry (either AccessShareLock, RowShareLock, or RowExclusiveLock depending on the RTE's role in the query). This patch creates the field and makes all creators of RTE nodes fill it in reasonably, but for the moment nothing much is done with it. The plan is to replace assorted post-parser logic that re-determines the right lockmode to use with simple uses of rte->rellockmode. For now, just add Asserts in each of those places that the rellockmode matches what they are computing today. (In some cases the match isn't perfect, so the Asserts are weaker than you might expect; but this seems OK, as per discussion.) This passes check-world for me, but it seems worth pushing in this state to see if the buildfarm finds any problems in cases I failed to test. catversion bump due to change of stored rules. Amit Langote, reviewed by David Rowley and Jesper Pedersen, and whacked around a bit more by me Discussion: https://postgr.es/m/468c85d9-540e-66a2-1dde-fec2b741e688@lab.ntt.co.jp
This commit is contained in:
@ -833,20 +833,21 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
|
||||
|
||||
if (stmt->relation)
|
||||
{
|
||||
LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
|
||||
RangeTblEntry *rte;
|
||||
TupleDesc tupDesc;
|
||||
List *attnums;
|
||||
ListCell *cur;
|
||||
RangeTblEntry *rte;
|
||||
|
||||
Assert(!stmt->query);
|
||||
|
||||
/* Open and lock the relation, using the appropriate lock type. */
|
||||
rel = heap_openrv(stmt->relation,
|
||||
(is_from ? RowExclusiveLock : AccessShareLock));
|
||||
rel = heap_openrv(stmt->relation, lockmode);
|
||||
|
||||
relid = RelationGetRelid(rel);
|
||||
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, false);
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, lockmode,
|
||||
NULL, false, false);
|
||||
rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
|
||||
|
||||
tupDesc = RelationGetDescr(rel);
|
||||
|
@ -528,6 +528,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
|
||||
rte->rtekind = RTE_RELATION;
|
||||
rte->relid = intoRelationAddr.objectId;
|
||||
rte->relkind = relkind;
|
||||
rte->rellockmode = RowExclusiveLock;
|
||||
rte->requiredPerms = ACL_INSERT;
|
||||
|
||||
for (attnum = 1; attnum <= intoRelationDesc->rd_att->natts; attnum++)
|
||||
|
@ -567,7 +567,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
|
||||
qual_expr = stringToNode(qual_value);
|
||||
|
||||
/* Add this rel to the parsestate's rangetable, for dependencies */
|
||||
addRangeTableEntryForRelation(qual_pstate, rel, NULL, false, false);
|
||||
addRangeTableEntryForRelation(qual_pstate, rel,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
qual_parse_rtable = qual_pstate->p_rtable;
|
||||
free_parsestate(qual_pstate);
|
||||
@ -589,8 +591,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
|
||||
with_check_qual = stringToNode(with_check_value);
|
||||
|
||||
/* Add this rel to the parsestate's rangetable, for dependencies */
|
||||
addRangeTableEntryForRelation(with_check_pstate, rel, NULL, false,
|
||||
false);
|
||||
addRangeTableEntryForRelation(with_check_pstate, rel,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
with_check_parse_rtable = with_check_pstate->p_rtable;
|
||||
free_parsestate(with_check_pstate);
|
||||
@ -752,11 +755,13 @@ CreatePolicy(CreatePolicyStmt *stmt)
|
||||
|
||||
/* Add for the regular security quals */
|
||||
rte = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
addRTEtoQuery(qual_pstate, rte, false, true, true);
|
||||
|
||||
/* Add for the with-check quals */
|
||||
rte = addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
addRTEtoQuery(with_check_pstate, rte, false, true, true);
|
||||
|
||||
@ -928,6 +933,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
ParseState *qual_pstate = make_parsestate(NULL);
|
||||
|
||||
rte = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
addRTEtoQuery(qual_pstate, rte, false, true, true);
|
||||
@ -950,6 +956,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
ParseState *with_check_pstate = make_parsestate(NULL);
|
||||
|
||||
rte = addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
addRTEtoQuery(with_check_pstate, rte, false, true, true);
|
||||
@ -1096,8 +1103,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
qual = stringToNode(qual_value);
|
||||
|
||||
/* Add this rel to the parsestate's rangetable, for dependencies */
|
||||
addRangeTableEntryForRelation(qual_pstate, target_table, NULL,
|
||||
false, false);
|
||||
addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
qual_parse_rtable = qual_pstate->p_rtable;
|
||||
free_parsestate(qual_pstate);
|
||||
@ -1137,8 +1145,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
with_check_qual = stringToNode(with_check_value);
|
||||
|
||||
/* Add this rel to the parsestate's rangetable, for dependencies */
|
||||
addRangeTableEntryForRelation(with_check_pstate, target_table, NULL,
|
||||
false, false);
|
||||
addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
with_check_parse_rtable = with_check_pstate->p_rtable;
|
||||
free_parsestate(with_check_pstate);
|
||||
|
@ -13632,7 +13632,8 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
|
||||
* rangetable entry. We need a ParseState for transformExpr.
|
||||
*/
|
||||
pstate = make_parsestate(NULL);
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, true);
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
|
||||
NULL, false, true);
|
||||
addRTEtoQuery(pstate, rte, true, true, true);
|
||||
|
||||
/* take care of any partition expressions */
|
||||
|
@ -577,10 +577,12 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
|
||||
* 'OLD' must always have varno equal to 1 and 'NEW' equal to 2.
|
||||
*/
|
||||
rte = addRangeTableEntryForRelation(pstate, rel,
|
||||
AccessShareLock,
|
||||
makeAlias("old", NIL),
|
||||
false, false);
|
||||
addRTEtoQuery(pstate, rte, false, true, true);
|
||||
rte = addRangeTableEntryForRelation(pstate, rel,
|
||||
AccessShareLock,
|
||||
makeAlias("new", NIL),
|
||||
false, false);
|
||||
addRTEtoQuery(pstate, rte, false, true, true);
|
||||
|
@ -353,7 +353,7 @@ DefineViewRules(Oid viewOid, Query *viewParse, bool replace)
|
||||
* by 2...
|
||||
*
|
||||
* These extra RT entries are not actually used in the query,
|
||||
* except for run-time permission checking.
|
||||
* except for run-time locking and permission checking.
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static Query *
|
||||
@ -386,9 +386,11 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
|
||||
* OLD first, then NEW....
|
||||
*/
|
||||
rt_entry1 = addRangeTableEntryForRelation(pstate, viewRel,
|
||||
AccessShareLock,
|
||||
makeAlias("old", NIL),
|
||||
false, false);
|
||||
rt_entry2 = addRangeTableEntryForRelation(pstate, viewRel,
|
||||
AccessShareLock,
|
||||
makeAlias("new", NIL),
|
||||
false, false);
|
||||
/* Must override addRangeTableEntry's default access-check flags */
|
||||
|
Reference in New Issue
Block a user