提交 81b5a62b 编写于 作者: H Heikki Linnakangas

Handle constants correctly in cdbpullup_findPathKeyExprInTargetList

If a PathKey contains a constant member, it can be evaluated without
any entries in the target list, and can always be returned in
cdbpullup_findPathKeyExprInTargetList. This fixes the "Unexpected intarnal
error" you got with the included test query.

Closes issue #348, reported by liruto. Thanks for the report!
上级 709bebd3
......@@ -379,52 +379,53 @@ cdbpullup_findPathKeyExprInTargetList(PathKey *item, List *targetlist)
ListCell *lc;
EquivalenceClass *eclass = item->pk_eclass;
/* Bail if targetlist is empty. */
if (!targetlist)
return NULL;
foreach(lc, eclass->ec_members)
{
EquivalenceMember *em = (EquivalenceMember *) lfirst(lc);
Expr *key = (Expr *) em->em_expr;
TargetEntry *tle;
/* A constant is OK regardless of the target list */
if (em->em_is_const)
return key;
/* Ignore possible RelabelType node atop the PathKey expr. */
if (IsA(key, RelabelType))
key = ((RelabelType *)key)->arg;
/* Check if targetlist is a List of TargetEntry */
if (IsA(linitial(targetlist), TargetEntry))
{
tle = tlist_member_ignoring_RelabelType(key, targetlist);
if (tle)
return key;
}
/* Planner's RelOptInfo targetlists don't have TargetEntry nodes */
else
if (targetlist)
{
ListCell *tcell;
/* Ignore possible RelabelType node atop the PathKey expr. */
if (IsA(key, RelabelType))
key = ((RelabelType *)key)->arg;
foreach(tcell, targetlist)
/* Check if targetlist is a List of TargetEntry */
if (IsA(linitial(targetlist), TargetEntry))
{
Expr *expr = (Expr *) lfirst(tcell);
TargetEntry *tle;
if (IsA(expr, RelabelType))
expr = ((RelabelType *)expr)->arg;
if (equal(expr, key))
tle = tlist_member_ignoring_RelabelType(key, targetlist);
if (tle)
return key;
}
}
/* Planner's RelOptInfo targetlists don't have TargetEntry nodes */
else
{
ListCell *tcell;
/* Return this item if all referenced Vars are in targetlist. */
if (!IsA(key, Var) &&
!cdbpullup_missingVarWalker((Node *) key, targetlist))
{
return key;
foreach(tcell, targetlist)
{
Expr *expr = (Expr *) lfirst(tcell);
if (IsA(expr, RelabelType))
expr = ((RelabelType *)expr)->arg;
if (equal(expr, key))
return key;
}
}
/* Return this item if all referenced Vars are in targetlist. */
if (!IsA(key, Var) &&
!cdbpullup_missingVarWalker((Node *) key, targetlist))
{
return key;
}
}
}
......
......@@ -1247,3 +1247,16 @@ where s_suppkey in (
foo10
(1 row)
--
-- Another case that failed at one point. (A planner bug in pulling up a
-- subquery with constant distribution key, 1, in the outer queries.)
--
create table nested_in_tbl(tc1 int, tc2 int) distributed by (tc1);
select * from nested_in_tbl t1 where tc1 in
(select 1 from nested_in_tbl t2 where tc1 in
(select 1 from nested_in_tbl t3 where t3.tc2 = t2.tc2));
tc1 | tc2
-----+-----
(0 rows)
drop table nested_in_tbl;
......@@ -1260,3 +1260,16 @@ where s_suppkey in (
foo10
(1 row)
--
-- Another case that failed at one point. (A planner bug in pulling up a
-- subquery with constant distribution key, 1, in the outer queries.)
--
create table nested_in_tbl(tc1 int, tc2 int) distributed by (tc1);
select * from nested_in_tbl t1 where tc1 in
(select 1 from nested_in_tbl t2 where tc1 in
(select 1 from nested_in_tbl t3 where t3.tc2 = t2.tc2));
tc1 | tc2
-----+-----
(0 rows)
drop table nested_in_tbl;
......@@ -568,3 +568,13 @@ select s_name from xsupplier
where s_suppkey in (
select g.l_suppkey from xlineitem g
) ;
--
-- Another case that failed at one point. (A planner bug in pulling up a
-- subquery with constant distribution key, 1, in the outer queries.)
--
create table nested_in_tbl(tc1 int, tc2 int) distributed by (tc1);
select * from nested_in_tbl t1 where tc1 in
(select 1 from nested_in_tbl t2 where tc1 in
(select 1 from nested_in_tbl t3 where t3.tc2 = t2.tc2));
drop table nested_in_tbl;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册