提交 cb46ac0e 编写于 作者: A Adam Lee 提交者: Adam Lee

Fix crash in transformSetOperationTree_internal()

In operation tree it's possible the leaf query has a different number of
columns than the previous ones. Greenplum used to fill the smaller number
of leaf infos before realizing it's different and breaking.

It works well before until Greenplum supports zero target queries like
"SELECT FROM t1", in this case the smaller number is zero, the list of
leaf infos refer to 0x7f7f7f7f7f7f7f7e, coming from palloc0(0).

Reproducer from Asim https://github.com/greenplum-db/gpdb/issues/7613

```
create table foo (a int, b int);
insert into foo select i,i from generate_series(1,21)i;

select from foo union select * from foo;
```

This commit fixes it by bypassing filling the leaf infos if they have
different numbers of columns.
上级 0f8c42fa
......@@ -2547,30 +2547,31 @@ transformSetOperationTree_internal(ParseState *pstate, SelectStmt *stmt,
setop_types->ncols = numCols;
setop_types->leafinfos = (List **) palloc0(setop_types->ncols * sizeof(List *));
}
i = 0;
foreach(tl, selectQuery->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
if (tle->resjunk)
continue;
/*
* It's possible that this leaf query has a different number
* of columns than the previous ones. That's an error, but
* we don't throw it here because we don't have the context
* needed for a good error message. We don't know which
* operation of the setop tree is the one where the number
* of columns between the left and right branches differ.
* Therefore, just return here as if nothing happened, and
* we'll catch that error in the parent instead.
*/
if (numCols == setop_types->ncols)
{
i = 0;
foreach(tl, selectQuery->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
setop_types->leafinfos[i] = lappend(setop_types->leafinfos[i],
(Node *) tle->expr);
i++;
if (tle->resjunk)
continue;
/*
* It's possible that this leaf query has a different number
* of columns than the previous ones. That's an error, but
* we don't throw it here because we don't have the context
* needed for a good error message. We don't know which
* operation of the setop tree is the one where the number
* of columns between the left and right branches differ.
* Therefore, just return here as if nothing happened, and
* we'll catch that error in the parent instead.
*/
if (i == setop_types->ncols)
break;
setop_types->leafinfos[i] = lappend(setop_types->leafinfos[i],
(Node *) tle->expr);
i++;
}
}
}
......
......@@ -1969,6 +1969,10 @@ select x.aa/100 aaa, x.c, y.c from cte1 x join cte1 y on x.aa=y.aa;
1 | one | one
(3 rows)
select from t2_ncols union select * from t2_ncols;
ERROR: each UNION query must have the same number of columns
LINE 1: select from t2_ncols union select * from t2_ncols;
^
--
-- Clean up
--
......
......@@ -557,6 +557,8 @@ select c, a from v1_ncols;
with cte1(aa, b, c, d) as (select a*100, b, c, d from t1_ncols union select * from t2_ncols)
select x.aa/100 aaa, x.c, y.c from cte1 x join cte1 y on x.aa=y.aa;
select from t2_ncols union select * from t2_ncols;
--
-- Clean up
--
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册