aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_clause.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2021-03-31 17:09:24 +0200
committerPeter Eisentraut <peter@eisentraut.org>2021-03-31 17:10:50 +0200
commit055fee7eb4dcc78e58672aef146334275e1cc40d (patch)
tree2034e69c471453e9aea59712b09d3fed95bce330 /src/backend/parser/parse_clause.c
parent27e1f14563cf982f1f4d71e21ef247866662a052 (diff)
downloadpostgresql-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.c32
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