summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2011-10-01 18:01:46 +0000
committerTom Lane2011-10-01 18:01:46 +0000
commit5ec6b7f1b87f0fa006b8e08a11cd4e99bcb67358 (patch)
tree3f178e9a5ffd1683278a94614e2b11779116a983
parent878b74e094a70e660e5ed365a2c4e1b41460515d (diff)
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
-rw-r--r--doc/src/sgml/ref/select.sgml5
-rw-r--r--doc/src/sgml/syntax.sgml6
-rw-r--r--src/backend/parser/parse_target.c42
-rw-r--r--src/test/regress/expected/aggregates.out6
-rw-r--r--src/test/regress/expected/subselect.out12
-rw-r--r--src/test/regress/expected/with.out4
6 files changed, 59 insertions, 16 deletions
diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml
index 7fb52833e8..636435fe1d 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 9119b60792..5ea755c572 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 9d4e580e47..2f2e87fd69 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 48610066bb..69926f7b79 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 e638f0a60c..4ea8211c69 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 a1b089921d..c4b045604b 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