diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2021-03-31 17:09:24 +0200 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2021-03-31 17:10:50 +0200 |
commit | 055fee7eb4dcc78e58672aef146334275e1cc40d (patch) | |
tree | 2034e69c471453e9aea59712b09d3fed95bce330 /src/backend/parser/parse_clause.c | |
parent | 27e1f14563cf982f1f4d71e21ef247866662a052 (diff) | |
download | postgresql-055fee7eb4dcc78e58672aef146334275e1cc40d.tar.gz postgresql-055fee7eb4dcc78e58672aef146334275e1cc40d.zip |
Allow an alias to be attached to a JOIN ... USING
This allows something like
SELECT ... FROM t1 JOIN t2 USING (a, b, c) AS x
where x has the columns a, b, c and unlike a regular alias it does not
hide the range variables of the tables being joined t1 and t2.
Per SQL:2016 feature F404 "Range variable for common column names".
Reviewed-by: Vik Fearing <vik.fearing@2ndquadrant.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/454638cf-d563-ab76-a585-2564428062af@2ndquadrant.com
Diffstat (limited to 'src/backend/parser/parse_clause.c')
-rw-r--r-- | src/backend/parser/parse_clause.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 5dfea460216..af80aa45936 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -1266,6 +1266,13 @@ transformFromClauseItem(ParseState *pstate, Node *n, } /* + * If a USING clause alias was specified, save the USING columns as + * its column list. + */ + if (j->join_using_alias) + j->join_using_alias->colnames = j->usingClause; + + /* * Now transform the join qualifications, if any. */ l_colnos = NIL; @@ -1460,6 +1467,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, res_colvars, l_colnos, r_colnos, + j->join_using_alias, j->alias, true); @@ -1494,6 +1502,30 @@ transformFromClauseItem(ParseState *pstate, Node *n, Assert(list_length(pstate->p_joinexprs) == j->rtindex); /* + * If the join has a USING alias, build a ParseNamespaceItem for that + * and add it to the list of nsitems in the join's input. + */ + if (j->join_using_alias) + { + ParseNamespaceItem *jnsitem; + + jnsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem)); + jnsitem->p_names = j->join_using_alias; + jnsitem->p_rte = nsitem->p_rte; + jnsitem->p_rtindex = nsitem->p_rtindex; + /* no need to copy the first N columns, just use res_nscolumns */ + jnsitem->p_nscolumns = res_nscolumns; + /* set default visibility flags; might get changed later */ + jnsitem->p_rel_visible = true; + jnsitem->p_cols_visible = true; + jnsitem->p_lateral_only = false; + jnsitem->p_lateral_ok = true; + /* Per SQL, we must check for alias conflicts */ + checkNameSpaceConflicts(pstate, list_make1(jnsitem), my_namespace); + my_namespace = lappend(my_namespace, jnsitem); + } + + /* * Prepare returned namespace list. If the JOIN has an alias then it * hides the contained RTEs completely; otherwise, the contained RTEs * are still visible as table names, but are not visible for |