From: Tom Lane Date: Tue, 3 Dec 2013 01:28:45 +0000 (-0500) Subject: Fix crash in assign_collations_walker for EXISTS with empty SELECT list. X-Git-Tag: REL9_4_BETA1~837 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ab321404c4f721a22e86f36f68fe5e94f65e54d;p=postgresql Fix crash in assign_collations_walker for EXISTS with empty SELECT list. We (I think I, actually) forgot about this corner case while coding collation resolution. Per bug #8648 from Arjen Nienhuis. --- diff --git a/src/backend/parser/parse_collate.c b/src/backend/parser/parse_collate.c index fe57c59618..c02f98acc7 100644 --- a/src/backend/parser/parse_collate.c +++ b/src/backend/parser/parse_collate.c @@ -484,16 +484,22 @@ assign_collations_walker(Node *node, assign_collations_context *context) * SubLink. Act as though the Query returns its first output * column, which indeed is what it does for EXPR_SUBLINK and * ARRAY_SUBLINK cases. In the cases where the SubLink - * returns boolean, this info will be ignored. + * returns boolean, this info will be ignored. Special case: + * in EXISTS, the Query might return no columns, in which case + * we need do nothing. * * We needn't recurse, since the Query is already processed. */ Query *qtree = (Query *) node; TargetEntry *tent; + if (qtree->targetList == NIL) + return false; tent = (TargetEntry *) linitial(qtree->targetList); Assert(IsA(tent, TargetEntry)); - Assert(!tent->resjunk); + if (tent->resjunk) + return false; + collation = exprCollation((Node *) tent->expr); /* collation doesn't change if it's converted to array */ strength = COLLATE_IMPLICIT; diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 1baf3d3e23..39c12f91e8 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -700,3 +700,13 @@ explain (verbose, costs off) One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) (8 rows) +-- +-- Check we behave sanely in corner case of empty SELECT list (bug #8648) +-- +create temp table nocolumns(); +select exists(select * from nocolumns); + exists +-------- + f +(1 row) + diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 0795d43534..278580797e 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -405,3 +405,9 @@ explain (verbose, costs off) explain (verbose, costs off) select x, x from (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss; + +-- +-- Check we behave sanely in corner case of empty SELECT list (bug #8648) +-- +create temp table nocolumns(); +select exists(select * from nocolumns);