From 5ec6b7f1b87f0fa006b8e08a11cd4e99bcb67358 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Sat, 1 Oct 2011 14:01:46 -0400 Subject: [PATCH] Improve generated column names for cases involving sub-SELECTs. We'll now use "exists" for EXISTS(SELECT ...), "array" for ARRAY(SELECT ...), or the sub-select's own result column name for a simple expression sub-select. Previously, you usually got "?column?" in such cases. Marti Raudsepp, reviewed by Kyotaro Horiugchi --- doc/src/sgml/ref/select.sgml | 5 +-- doc/src/sgml/syntax.sgml | 6 ++-- src/backend/parser/parse_target.c | 42 ++++++++++++++++++++++++ src/test/regress/expected/aggregates.out | 6 ++-- src/test/regress/expected/subselect.out | 12 +++---- src/test/regress/expected/with.out | 4 +-- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 7fb52833e8a..636435fe1d8 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -758,8 +758,9 @@ UNBOUNDED FOLLOWING If you do not specify a column name, a name is chosen automatically by <productname>PostgreSQL</productname>. If the column's expression is a simple column reference then the chosen name is the same as that - column's name; in more complex cases a generated name looking like - <literal>?column<replaceable>N</>?</literal> is usually chosen. + column's name. In more complex cases a function or type name may be + used, or the system may fall back on a generated name such as + <literal>?column?</literal>. </para> <para> diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 9119b60792e..5ea755c5725 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -2109,9 +2109,9 @@ SELECT ARRAY[]::integer[]; bracketed) subquery. For example: <programlisting> SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%'); - ?column? -------------------------------------------------------------- - {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31} + array +----------------------------------------------------------------------- + {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31,2412,2413} (1 row) </programlisting> The subquery must return a single column. The resulting diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 9d4e580e476..2f2e87fd698 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -1610,6 +1610,48 @@ FigureColnameInternal(Node *node, char **name) break; case T_CollateClause: return FigureColnameInternal(((CollateClause *) node)->arg, name); + case T_SubLink: + switch (((SubLink *) node)->subLinkType) + { + case EXISTS_SUBLINK: + *name = "exists"; + return 2; + case ARRAY_SUBLINK: + *name = "array"; + return 2; + case EXPR_SUBLINK: + { + /* Get column name of the subquery's single target */ + SubLink *sublink = (SubLink *) node; + Query *query = (Query *) sublink->subselect; + + /* + * The subquery has probably already been transformed, + * but let's be careful and check that. (The reason + * we can see a transformed subquery here is that + * transformSubLink is lazy and modifies the SubLink + * node in-place.) + */ + if (IsA(query, Query)) + { + TargetEntry *te = (TargetEntry *) linitial(query->targetList); + + if (te->resname) + { + *name = te->resname; + return 2; + } + } + } + break; + /* As with other operator-like nodes, these have no names */ + case ALL_SUBLINK: + case ANY_SUBLINK: + case ROWCOMPARE_SUBLINK: + case CTE_SUBLINK: + break; + } + break; case T_CaseExpr: strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult, name); diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 48610066bbd..69926f7b79e 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -300,9 +300,9 @@ LINE 4: where sum(distinct a.four + b.four) = b.four)... select (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1))) from tenk1 o; - ?column? ----------- - 9999 + max +------ + 9999 (1 row) -- diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index e638f0a60c3..4ea8211c692 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -490,20 +490,20 @@ select view_a from view_a; (1 row) select (select view_a) from view_a; - ?column? ----------- + view_a +-------- (42) (1 row) select (select (select view_a)) from view_a; - ?column? ----------- + view_a +-------- (42) (1 row) select (select (a.*)::text) from view_a a; - ?column? ----------- + a +------ (42) (1 row) diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out index a1b089921d3..c4b045604b6 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -1065,7 +1065,7 @@ with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q; select ( with cte(foo) as ( values(f1) ) select (select foo from cte) ) from int4_tbl; - ?column? + foo ------------- 0 123456 @@ -1077,7 +1077,7 @@ from int4_tbl; select ( with cte(foo) as ( values(f1) ) values((select foo from cte)) ) from int4_tbl; - ?column? + column1 ------------- 0 123456 -- GitLab