diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-01-02 11:29:01 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-01-02 11:29:01 -0500 |
commit | 5815696bc66b3092f6361f53e0394909647042c8 (patch) | |
tree | 590a95ba0a43325dc14b7fa8f88222c5ef7110a3 /src/backend/parser/parse_utilcmd.c | |
parent | 198c7153dccb11950e3030dec564fdc6e59b4451 (diff) | |
download | postgresql-5815696bc66b3092f6361f53e0394909647042c8.tar.gz postgresql-5815696bc66b3092f6361f53e0394909647042c8.zip |
Make parser rely more heavily on the ParseNamespaceItem data structure.
When I added the ParseNamespaceItem data structure (in commit 5ebaaa494),
it wasn't very tightly integrated into the parser's APIs. In the wake of
adding p_rtindex to that struct (commit b541e9acc), 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
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 100 |
1 files changed, 51 insertions, 49 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index c593e3f279f..42095ab8306 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -2598,7 +2598,7 @@ IndexStmt * transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) { ParseState *pstate; - RangeTblEntry *rte; + ParseNamespaceItem *nsitem; ListCell *l; Relation rel; @@ -2622,12 +2622,12 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) * relation, but we still need to open it. */ rel = relation_open(relid, NoLock); - rte = addRangeTableEntryForRelation(pstate, rel, - AccessShareLock, - NULL, false, true); + nsitem = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, + NULL, false, true); /* no to join list, yes to namespaces */ - addRTEtoQuery(pstate, rte, false, true, true); + addNSItemToQuery(pstate, nsitem, false, true, true); /* take care of the where clause */ if (stmt->whereClause) @@ -2707,8 +2707,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, { Relation rel; ParseState *pstate; - RangeTblEntry *oldrte; - RangeTblEntry *newrte; + ParseNamespaceItem *oldnsitem; + ParseNamespaceItem *newnsitem; /* * To avoid deadlock, make sure the first thing we do is grab @@ -2729,20 +2729,20 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, /* * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to 2. - * Set up their RTEs in the main pstate for use in parsing the rule - * qualification. + * Set up their ParseNamespaceItems in the main pstate for use in parsing + * the rule qualification. */ - oldrte = addRangeTableEntryForRelation(pstate, rel, - AccessShareLock, - makeAlias("old", NIL), - false, false); - newrte = addRangeTableEntryForRelation(pstate, rel, - AccessShareLock, - makeAlias("new", NIL), - false, false); + oldnsitem = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, + makeAlias("old", NIL), + false, false); + newnsitem = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, + makeAlias("new", NIL), + false, false); /* Must override addRangeTableEntry's default access-check flags */ - oldrte->requiredPerms = 0; - newrte->requiredPerms = 0; + oldnsitem->p_rte->requiredPerms = 0; + newnsitem->p_rte->requiredPerms = 0; /* * They must be in the namespace too for lookup purposes, but only add the @@ -2754,17 +2754,17 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, switch (stmt->event) { case CMD_SELECT: - addRTEtoQuery(pstate, oldrte, false, true, true); + addNSItemToQuery(pstate, oldnsitem, false, true, true); break; case CMD_UPDATE: - addRTEtoQuery(pstate, oldrte, false, true, true); - addRTEtoQuery(pstate, newrte, false, true, true); + addNSItemToQuery(pstate, oldnsitem, false, true, true); + addNSItemToQuery(pstate, newnsitem, false, true, true); break; case CMD_INSERT: - addRTEtoQuery(pstate, newrte, false, true, true); + addNSItemToQuery(pstate, newnsitem, false, true, true); break; case CMD_DELETE: - addRTEtoQuery(pstate, oldrte, false, true, true); + addNSItemToQuery(pstate, oldnsitem, false, true, true); break; default: elog(ERROR, "unrecognized event type: %d", @@ -2832,18 +2832,18 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, * nor "*" in the rule actions. We decide later whether to put * them in the joinlist. */ - oldrte = addRangeTableEntryForRelation(sub_pstate, rel, - AccessShareLock, - makeAlias("old", NIL), - false, false); - newrte = addRangeTableEntryForRelation(sub_pstate, rel, - AccessShareLock, - makeAlias("new", NIL), - false, false); - oldrte->requiredPerms = 0; - newrte->requiredPerms = 0; - addRTEtoQuery(sub_pstate, oldrte, false, true, false); - addRTEtoQuery(sub_pstate, newrte, false, true, false); + oldnsitem = addRangeTableEntryForRelation(sub_pstate, rel, + AccessShareLock, + makeAlias("old", NIL), + false, false); + newnsitem = addRangeTableEntryForRelation(sub_pstate, rel, + AccessShareLock, + makeAlias("new", NIL), + false, false); + oldnsitem->p_rte->requiredPerms = 0; + newnsitem->p_rte->requiredPerms = 0; + addNSItemToQuery(sub_pstate, oldnsitem, false, true, false); + addNSItemToQuery(sub_pstate, newnsitem, false, true, false); /* Transform the rule action statement */ top_subqry = transformStmt(sub_pstate, @@ -2967,6 +2967,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, */ if (has_old || (has_new && stmt->event == CMD_UPDATE)) { + RangeTblRef *rtr; + /* * If sub_qry is a setop, manipulating its jointree will do no * good at all, because the jointree is dummy. (This should be @@ -2976,11 +2978,11 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented"))); - /* hack so we can use addRTEtoQuery() */ - sub_pstate->p_rtable = sub_qry->rtable; - sub_pstate->p_joinlist = sub_qry->jointree->fromlist; - addRTEtoQuery(sub_pstate, oldrte, true, false, false); - sub_qry->jointree->fromlist = sub_pstate->p_joinlist; + /* hackishly add OLD to the already-built FROM clause */ + rtr = makeNode(RangeTblRef); + rtr->rtindex = oldnsitem->p_rtindex; + sub_qry->jointree->fromlist = + lappend(sub_qry->jointree->fromlist, rtr); } newactions = lappend(newactions, top_subqry); @@ -3025,7 +3027,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, List *newcmds = NIL; bool skipValidation = true; AlterTableCmd *newcmd; - RangeTblEntry *rte; + ParseNamespaceItem *nsitem; /* * We must not scribble on the passed-in AlterTableStmt, so copy it. (This @@ -3040,13 +3042,13 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, /* Set up pstate */ pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; - rte = addRangeTableEntryForRelation(pstate, - rel, - AccessShareLock, - NULL, - false, - true); - addRTEtoQuery(pstate, rte, false, true, true); + nsitem = addRangeTableEntryForRelation(pstate, + rel, + AccessShareLock, + NULL, + false, + true); + addNSItemToQuery(pstate, nsitem, false, true, true); /* Set up CreateStmtContext */ cxt.pstate = pstate; |