1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-03 15:22:11 +03:00

Merge parser's p_relnamespace and p_varnamespace lists into a single list.

Now that we are storing structs in these lists, the distinction between
the two lists can be represented with a couple of extra flags while using
only a single list.  This simplifies the code and should save a little
bit of palloc traffic, since the majority of RTEs are represented in both
lists anyway.
This commit is contained in:
Tom Lane
2012-08-08 16:41:04 -04:00
parent 8143a56854
commit f630157496
5 changed files with 206 additions and 150 deletions

View File

@@ -54,25 +54,17 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,
* p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that
* will become the fromlist of the query's top-level FromExpr node.
*
* p_relnamespace: list of ParseNamespaceItems that represents the current
* namespace for table lookup, ie, those RTEs that are accessible by
* qualified names. (This may be just a subset of the whole rtable.)
*
* p_varnamespace: list of ParseNamespaceItems that represents the current
* namespace for column lookup, ie, those RTEs that are accessible by
* unqualified names. This is different from p_relnamespace because a JOIN
* without an alias does not hide the contained tables (so they must be in
* p_relnamespace) but it does hide their columns (unqualified references to
* the columns must refer to the JOIN, not the member tables). Other special
* RTEs such as NEW/OLD for rules may also appear in just one of these lists.
* p_namespace: list of ParseNamespaceItems that represents the current
* namespace for table and column lookup. (The RTEs listed here may be just
* a subset of the whole rtable. See ParseNamespaceItem comments below.)
*
* p_lateral_active: TRUE if we are currently parsing a LATERAL subexpression
* of this parse level. This makes p_lateral_only namespace items visible,
* whereas they are not visible when p_lateral_active is FALSE.
*
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
* at the moment. This is entirely different from p_relnamespace because
* a CTE is not an RTE, rather "visibility" means you could make an RTE.
* at the moment. This is entirely different from p_namespace because a CTE
* is not an RTE, rather "visibility" means you could make an RTE from it.
*
* p_future_ctes: list of CommonTableExprs (WITH items) that are not yet
* visible due to scope rules. This is used to help improve error messages.
@@ -94,8 +86,8 @@ struct ParseState
List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */
List *p_joinlist; /* join items so far (will become FromExpr
* node's fromlist) */
List *p_relnamespace; /* current namespace for relations */
List *p_varnamespace; /* current namespace for columns */
List *p_namespace; /* currently-referenceable RTEs (List of
* ParseNamespaceItem) */
bool p_lateral_active; /* p_lateral_only items visible? */
List *p_ctenamespace; /* current namespace for common table exprs */
List *p_future_ctes; /* common table exprs not yet in namespace */
@@ -125,10 +117,37 @@ struct ParseState
void *p_ref_hook_state; /* common passthrough link for above */
};
/* An element of p_relnamespace or p_varnamespace */
/*
* An element of a namespace list.
*
* Namespace items with p_rel_visible set define which RTEs are accessible by
* qualified names, while those with p_cols_visible set define which RTEs are
* accessible by unqualified names. These sets are different because a JOIN
* without an alias does not hide the contained tables (so they must be
* visible for qualified references) but it does hide their columns
* (unqualified references to the columns refer to the JOIN, not the member
* tables, so we must not complain that such a reference is ambiguous).
* Various special RTEs such as NEW/OLD for rules may also appear with only
* one flag set.
*
* While processing the FROM clause, namespace items may appear with
* p_lateral_only set, meaning they are visible only to LATERAL
* subexpressions. (The pstate's p_lateral_active flag tells whether we are
* inside such a subexpression at the moment.) If p_lateral_ok is not set,
* it's an error to actually use such a namespace item. One might think it
* would be better to just exclude such items from visibility, but the wording
* of SQL:2008 requires us to do it this way.
*
* At no time should a namespace list contain two entries that conflict
* according to the rules in checkNameSpaceConflicts; but note that those
* are more complicated than "must have different alias names", so in practice
* code searching a namespace list has to check for ambiguous references.
*/
typedef struct ParseNamespaceItem
{
RangeTblEntry *p_rte; /* The relation's rangetable entry */
bool p_rel_visible; /* Relation name is visible? */
bool p_cols_visible; /* Column names visible as unqualified refs? */
bool p_lateral_only; /* Is only visible to LATERAL expressions? */
bool p_lateral_ok; /* If so, does join type allow use? */
} ParseNamespaceItem;