mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit5ebaaa494
), it wasn't very tightly integrated into the parser's APIs. In the wake of adding p_rtindex to that struct (commitb541e9acc
), there is a good reason to make more use of it: by passing around ParseNamespaceItem pointers instead of bare RTE pointers, we can get rid of various messy methods for passing back or deducing the rangetable index of an RTE during parsing. Hence, refactor the addRangeTableEntryXXX functions to build and return a ParseNamespaceItem struct, not just the RTE proper; and replace addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem rather than building one internally. Also, add per-column data (a ParseNamespaceColumn array) to each ParseNamespaceItem. These arrays are built during addRangeTableEntryXXX, where we have column type data at hand so that it's nearly free to fill the data structure. Later, when we need to build Vars referencing RTEs, we can use the ParseNamespaceColumn info to avoid the rather expensive operations done in get_rte_attribute_type() or expandRTE(). get_rte_attribute_type() is indeed dead code now, so I've removed it. This makes for a useful improvement in parse analysis speed, around 20% in one moderately-complex test query. The ParseNamespaceColumn structs also include Var identity information (varno/varattno). That info isn't actually being used in this patch, except that p_varno == 0 is a handy test for a dropped column. A follow-on patch will make more use of it. Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
This commit is contained in:
@ -882,6 +882,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
|
||||
if (stmt->relation)
|
||||
{
|
||||
LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
|
||||
ParseNamespaceItem *nsitem;
|
||||
RangeTblEntry *rte;
|
||||
TupleDesc tupDesc;
|
||||
List *attnums;
|
||||
@ -894,14 +895,15 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
|
||||
|
||||
relid = RelationGetRelid(rel);
|
||||
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, lockmode,
|
||||
NULL, false, false);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
|
||||
NULL, false, false);
|
||||
rte = nsitem->p_rte;
|
||||
rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
|
||||
|
||||
if (stmt->whereClause)
|
||||
{
|
||||
/* add rte to column namespace */
|
||||
addRTEtoQuery(pstate, rte, false, true, true);
|
||||
/* add nsitem to query namespace */
|
||||
addNSItemToQuery(pstate, nsitem, false, true, true);
|
||||
|
||||
/* Transform the raw expression tree */
|
||||
whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
|
||||
|
@ -568,9 +568,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,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
(void) addRangeTableEntryForRelation(qual_pstate, rel,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
qual_parse_rtable = qual_pstate->p_rtable;
|
||||
free_parsestate(qual_pstate);
|
||||
@ -592,9 +592,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,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
(void) addRangeTableEntryForRelation(with_check_pstate, rel,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
with_check_parse_rtable = with_check_pstate->p_rtable;
|
||||
free_parsestate(with_check_pstate);
|
||||
@ -699,7 +699,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
|
||||
ArrayType *role_ids;
|
||||
ParseState *qual_pstate;
|
||||
ParseState *with_check_pstate;
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
Node *qual;
|
||||
Node *with_check_qual;
|
||||
ScanKeyData skey[2];
|
||||
@ -755,16 +755,16 @@ CreatePolicy(CreatePolicyStmt *stmt)
|
||||
target_table = relation_open(table_id, NoLock);
|
||||
|
||||
/* Add for the regular security quals */
|
||||
rte = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
addRTEtoQuery(qual_pstate, rte, false, true, true);
|
||||
nsitem = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
addNSItemToQuery(qual_pstate, nsitem, 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);
|
||||
nsitem = addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
addNSItemToQuery(with_check_pstate, nsitem, false, true, true);
|
||||
|
||||
qual = transformWhereClause(qual_pstate,
|
||||
copyObject(stmt->qual),
|
||||
@ -933,14 +933,14 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
/* Parse the using policy clause */
|
||||
if (stmt->qual)
|
||||
{
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
ParseState *qual_pstate = make_parsestate(NULL);
|
||||
|
||||
rte = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
nsitem = addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
addRTEtoQuery(qual_pstate, rte, false, true, true);
|
||||
addNSItemToQuery(qual_pstate, nsitem, false, true, true);
|
||||
|
||||
qual = transformWhereClause(qual_pstate, copyObject(stmt->qual),
|
||||
EXPR_KIND_POLICY,
|
||||
@ -956,14 +956,14 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
/* Parse the with-check policy clause */
|
||||
if (stmt->with_check)
|
||||
{
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
ParseState *with_check_pstate = make_parsestate(NULL);
|
||||
|
||||
rte = addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
nsitem = addRangeTableEntryForRelation(with_check_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
addRTEtoQuery(with_check_pstate, rte, false, true, true);
|
||||
addNSItemToQuery(with_check_pstate, nsitem, false, true, true);
|
||||
|
||||
with_check_qual = transformWhereClause(with_check_pstate,
|
||||
copyObject(stmt->with_check),
|
||||
@ -1107,9 +1107,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
|
||||
qual = stringToNode(qual_value);
|
||||
|
||||
/* Add this rel to the parsestate's rangetable, for dependencies */
|
||||
addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
(void) addRangeTableEntryForRelation(qual_pstate, target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
qual_parse_rtable = qual_pstate->p_rtable;
|
||||
free_parsestate(qual_pstate);
|
||||
@ -1149,9 +1149,10 @@ 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,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
(void) addRangeTableEntryForRelation(with_check_pstate,
|
||||
target_table,
|
||||
AccessShareLock,
|
||||
NULL, false, false);
|
||||
|
||||
with_check_parse_rtable = with_check_pstate->p_rtable;
|
||||
free_parsestate(with_check_pstate);
|
||||
|
@ -918,7 +918,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
|
||||
defaultPartOid;
|
||||
Relation parent,
|
||||
defaultRel = NULL;
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
|
||||
/* Already have strong enough lock on the parent */
|
||||
parent = table_open(parentId, NoLock);
|
||||
@ -962,13 +962,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
|
||||
pstate->p_sourcetext = queryString;
|
||||
|
||||
/*
|
||||
* Add an RTE containing this relation, so that transformExpr called
|
||||
* on partition bound expressions is able to report errors using a
|
||||
* proper context.
|
||||
* Add an nsitem containing this relation, so that transformExpr
|
||||
* called on partition bound expressions is able to report errors
|
||||
* using a proper context.
|
||||
*/
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
|
||||
NULL, false, false);
|
||||
addRTEtoQuery(pstate, rte, false, true, true);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
|
||||
NULL, false, false);
|
||||
addNSItemToQuery(pstate, nsitem, false, true, true);
|
||||
|
||||
bound = transformPartitionBound(pstate, parent, stmt->partbound);
|
||||
|
||||
/*
|
||||
@ -14970,7 +14971,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
|
||||
{
|
||||
PartitionSpec *newspec;
|
||||
ParseState *pstate;
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
ListCell *l;
|
||||
|
||||
newspec = makeNode(PartitionSpec);
|
||||
@ -15004,9 +15005,9 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
|
||||
* rangetable entry. We need a ParseState for transformExpr.
|
||||
*/
|
||||
pstate = make_parsestate(NULL);
|
||||
rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
|
||||
NULL, false, true);
|
||||
addRTEtoQuery(pstate, rte, true, true, true);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
|
||||
NULL, false, true);
|
||||
addNSItemToQuery(pstate, nsitem, true, true, true);
|
||||
|
||||
/* take care of any partition expressions */
|
||||
foreach(l, partspec->partParams)
|
||||
|
@ -565,7 +565,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
|
||||
if (!whenClause && stmt->whenClause)
|
||||
{
|
||||
ParseState *pstate;
|
||||
RangeTblEntry *rte;
|
||||
ParseNamespaceItem *nsitem;
|
||||
List *varList;
|
||||
ListCell *lc;
|
||||
|
||||
@ -574,20 +574,20 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
|
||||
pstate->p_sourcetext = queryString;
|
||||
|
||||
/*
|
||||
* Set up RTEs for OLD and NEW references.
|
||||
* Set up nsitems for OLD and NEW references.
|
||||
*
|
||||
* '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);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, rel,
|
||||
AccessShareLock,
|
||||
makeAlias("old", NIL),
|
||||
false, false);
|
||||
addNSItemToQuery(pstate, nsitem, false, true, true);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, rel,
|
||||
AccessShareLock,
|
||||
makeAlias("new", NIL),
|
||||
false, false);
|
||||
addNSItemToQuery(pstate, nsitem, false, true, true);
|
||||
|
||||
/* Transform expression. Copy to be sure we don't modify original */
|
||||
whenClause = transformWhereClause(pstate,
|
||||
|
@ -341,6 +341,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
|
||||
{
|
||||
Relation viewRel;
|
||||
List *new_rt;
|
||||
ParseNamespaceItem *nsitem;
|
||||
RangeTblEntry *rt_entry1,
|
||||
*rt_entry2;
|
||||
ParseState *pstate;
|
||||
@ -365,14 +366,17 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
|
||||
* Create the 2 new range table entries and form the new range table...
|
||||
* 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);
|
||||
nsitem = addRangeTableEntryForRelation(pstate, viewRel,
|
||||
AccessShareLock,
|
||||
makeAlias("old", NIL),
|
||||
false, false);
|
||||
rt_entry1 = nsitem->p_rte;
|
||||
nsitem = addRangeTableEntryForRelation(pstate, viewRel,
|
||||
AccessShareLock,
|
||||
makeAlias("new", NIL),
|
||||
false, false);
|
||||
rt_entry2 = nsitem->p_rte;
|
||||
|
||||
/* Must override addRangeTableEntry's default access-check flags */
|
||||
rt_entry1->requiredPerms = 0;
|
||||
rt_entry2->requiredPerms = 0;
|
||||
|
Reference in New Issue
Block a user