Commit d479e37e authored by Tom Lane's avatar Tom Lane

Fix Assert failure induced by commit 215b43cd.

I'd somehow talked myself into believing that set_append_rel_size
doesn't need to worry about getting back an AND clause when it applies
eval_const_expressions to the result of adjust_appendrel_attrs (that is,
transposing the appendrel parent's restriction clauses for one child).
But that is nonsense, and Andreas Seltenreich's fuzz tester soon
turned up a counterexample.  Put back the make_ands_implicit step
that was there before, and add a regression test covering the case.

Report: https://postgr.es/m/878tq6vja6.fsf@ansel.ydns.eu
parent 18220053
...@@ -896,7 +896,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, ...@@ -896,7 +896,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
{ {
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
Node *childqual; Node *childqual;
bool pseudoconstant; ListCell *lc2;
Assert(IsA(rinfo, RestrictInfo)); Assert(IsA(rinfo, RestrictInfo));
childqual = adjust_appendrel_attrs(root, childqual = adjust_appendrel_attrs(root,
...@@ -916,10 +916,16 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, ...@@ -916,10 +916,16 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
/* Restriction reduces to constant TRUE, so drop it */ /* Restriction reduces to constant TRUE, so drop it */
continue; continue;
} }
/* might have gotten an AND clause, if so flatten it */
foreach(lc2, make_ands_implicit((Expr *) childqual))
{
Node *onecq = (Node *) lfirst(lc2);
bool pseudoconstant;
/* check for pseudoconstant (no Vars or volatile functions) */ /* check for pseudoconstant (no Vars or volatile functions) */
pseudoconstant = pseudoconstant =
!contain_vars_of_level(childqual, 0) && !contain_vars_of_level(onecq, 0) &&
!contain_volatile_functions(childqual); !contain_volatile_functions(onecq);
if (pseudoconstant) if (pseudoconstant)
{ {
/* tell createplan.c to check for gating quals */ /* tell createplan.c to check for gating quals */
...@@ -927,7 +933,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, ...@@ -927,7 +933,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
} }
/* reconstitute RestrictInfo with appropriate properties */ /* reconstitute RestrictInfo with appropriate properties */
childquals = lappend(childquals, childquals = lappend(childquals,
make_restrictinfo((Expr *) childqual, make_restrictinfo((Expr *) onecq,
rinfo->is_pushed_down, rinfo->is_pushed_down,
rinfo->outerjoin_delayed, rinfo->outerjoin_delayed,
pseudoconstant, pseudoconstant,
...@@ -936,6 +942,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, ...@@ -936,6 +942,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
/* track minimum security level among child quals */ /* track minimum security level among child quals */
cq_min_security = Min(cq_min_security, rinfo->security_level); cq_min_security = Min(cq_min_security, rinfo->security_level);
} }
}
/* /*
* In addition to the quals inherited from the parent, we might have * In addition to the quals inherited from the parent, we might have
......
...@@ -720,3 +720,33 @@ select * from ...@@ -720,3 +720,33 @@ select * from
drop table t3; drop table t3;
drop function expensivefunc(int); drop function expensivefunc(int);
-- Test handling of appendrel quals that const-simplify into an AND
explain (costs off)
select * from
(select *, 0 as x from int8_tbl a
union all
select *, 1 as x from int8_tbl b) ss
where (x = 0) or (q1 >= q2 and q1 <= q2);
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on int8_tbl a
-> Seq Scan on int8_tbl b
Filter: ((q1 >= q2) AND (q1 <= q2))
(4 rows)
select * from
(select *, 0 as x from int8_tbl a
union all
select *, 1 as x from int8_tbl b) ss
where (x = 0) or (q1 >= q2 and q1 <= q2);
q1 | q2 | x
------------------+-------------------+---
123 | 456 | 0
123 | 4567890123456789 | 0
4567890123456789 | 123 | 0
4567890123456789 | 4567890123456789 | 0
4567890123456789 | -4567890123456789 | 0
4567890123456789 | 4567890123456789 | 1
(6 rows)
...@@ -322,3 +322,16 @@ select * from ...@@ -322,3 +322,16 @@ select * from
drop table t3; drop table t3;
drop function expensivefunc(int); drop function expensivefunc(int);
-- Test handling of appendrel quals that const-simplify into an AND
explain (costs off)
select * from
(select *, 0 as x from int8_tbl a
union all
select *, 1 as x from int8_tbl b) ss
where (x = 0) or (q1 >= q2 and q1 <= q2);
select * from
(select *, 0 as x from int8_tbl a
union all
select *, 1 as x from int8_tbl b) ss
where (x = 0) or (q1 >= q2 and q1 <= q2);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment