mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-11 19:20:40 +08:00
Fix Assert failure induced by commit 215b43cdc
.
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
This commit is contained in:
parent
182200531a
commit
d479e37e3d
@ -896,7 +896,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
|
||||
{
|
||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
|
||||
Node *childqual;
|
||||
bool pseudoconstant;
|
||||
ListCell *lc2;
|
||||
|
||||
Assert(IsA(rinfo, RestrictInfo));
|
||||
childqual = adjust_appendrel_attrs(root,
|
||||
@ -916,25 +916,32 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
|
||||
/* Restriction reduces to constant TRUE, so drop it */
|
||||
continue;
|
||||
}
|
||||
/* check for pseudoconstant (no Vars or volatile functions) */
|
||||
pseudoconstant =
|
||||
!contain_vars_of_level(childqual, 0) &&
|
||||
!contain_volatile_functions(childqual);
|
||||
if (pseudoconstant)
|
||||
/* might have gotten an AND clause, if so flatten it */
|
||||
foreach(lc2, make_ands_implicit((Expr *) childqual))
|
||||
{
|
||||
/* tell createplan.c to check for gating quals */
|
||||
root->hasPseudoConstantQuals = true;
|
||||
Node *onecq = (Node *) lfirst(lc2);
|
||||
bool pseudoconstant;
|
||||
|
||||
/* check for pseudoconstant (no Vars or volatile functions) */
|
||||
pseudoconstant =
|
||||
!contain_vars_of_level(onecq, 0) &&
|
||||
!contain_volatile_functions(onecq);
|
||||
if (pseudoconstant)
|
||||
{
|
||||
/* tell createplan.c to check for gating quals */
|
||||
root->hasPseudoConstantQuals = true;
|
||||
}
|
||||
/* reconstitute RestrictInfo with appropriate properties */
|
||||
childquals = lappend(childquals,
|
||||
make_restrictinfo((Expr *) onecq,
|
||||
rinfo->is_pushed_down,
|
||||
rinfo->outerjoin_delayed,
|
||||
pseudoconstant,
|
||||
rinfo->security_level,
|
||||
NULL, NULL, NULL));
|
||||
/* track minimum security level among child quals */
|
||||
cq_min_security = Min(cq_min_security, rinfo->security_level);
|
||||
}
|
||||
/* reconstitute RestrictInfo with appropriate properties */
|
||||
childquals = lappend(childquals,
|
||||
make_restrictinfo((Expr *) childqual,
|
||||
rinfo->is_pushed_down,
|
||||
rinfo->outerjoin_delayed,
|
||||
pseudoconstant,
|
||||
rinfo->security_level,
|
||||
NULL, NULL, NULL));
|
||||
/* track minimum security level among child quals */
|
||||
cq_min_security = Min(cq_min_security, rinfo->security_level);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -720,3 +720,33 @@ select * from
|
||||
|
||||
drop table t3;
|
||||
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
|
||||
|
||||
drop table t3;
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user