Skip to content

Commit d479e37

Browse files
committed
Fix Assert failure induced by commit 215b43c.
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
1 parent 1822005 commit d479e37

File tree

3 files changed

+68
-18
lines changed

3 files changed

+68
-18
lines changed

src/backend/optimizer/path/allpaths.c

+25-18
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
896896
{
897897
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
898898
Node *childqual;
899-
bool pseudoconstant;
899+
ListCell *lc2;
900900

901901
Assert(IsA(rinfo, RestrictInfo));
902902
childqual = adjust_appendrel_attrs(root,
@@ -916,25 +916,32 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
916916
/* Restriction reduces to constant TRUE, so drop it */
917917
continue;
918918
}
919-
/* check for pseudoconstant (no Vars or volatile functions) */
920-
pseudoconstant =
921-
!contain_vars_of_level(childqual, 0) &&
922-
!contain_volatile_functions(childqual);
923-
if (pseudoconstant)
919+
/* might have gotten an AND clause, if so flatten it */
920+
foreach(lc2, make_ands_implicit((Expr *) childqual))
924921
{
925-
/* tell createplan.c to check for gating quals */
926-
root->hasPseudoConstantQuals = true;
922+
Node *onecq = (Node *) lfirst(lc2);
923+
bool pseudoconstant;
924+
925+
/* check for pseudoconstant (no Vars or volatile functions) */
926+
pseudoconstant =
927+
!contain_vars_of_level(onecq, 0) &&
928+
!contain_volatile_functions(onecq);
929+
if (pseudoconstant)
930+
{
931+
/* tell createplan.c to check for gating quals */
932+
root->hasPseudoConstantQuals = true;
933+
}
934+
/* reconstitute RestrictInfo with appropriate properties */
935+
childquals = lappend(childquals,
936+
make_restrictinfo((Expr *) onecq,
937+
rinfo->is_pushed_down,
938+
rinfo->outerjoin_delayed,
939+
pseudoconstant,
940+
rinfo->security_level,
941+
NULL, NULL, NULL));
942+
/* track minimum security level among child quals */
943+
cq_min_security = Min(cq_min_security, rinfo->security_level);
927944
}
928-
/* reconstitute RestrictInfo with appropriate properties */
929-
childquals = lappend(childquals,
930-
make_restrictinfo((Expr *) childqual,
931-
rinfo->is_pushed_down,
932-
rinfo->outerjoin_delayed,
933-
pseudoconstant,
934-
rinfo->security_level,
935-
NULL, NULL, NULL));
936-
/* track minimum security level among child quals */
937-
cq_min_security = Min(cq_min_security, rinfo->security_level);
938945
}
939946

940947
/*

src/test/regress/expected/union.out

+30
Original file line numberDiff line numberDiff line change
@@ -720,3 +720,33 @@ select * from
720720

721721
drop table t3;
722722
drop function expensivefunc(int);
723+
-- Test handling of appendrel quals that const-simplify into an AND
724+
explain (costs off)
725+
select * from
726+
(select *, 0 as x from int8_tbl a
727+
union all
728+
select *, 1 as x from int8_tbl b) ss
729+
where (x = 0) or (q1 >= q2 and q1 <= q2);
730+
QUERY PLAN
731+
---------------------------------------------
732+
Append
733+
-> Seq Scan on int8_tbl a
734+
-> Seq Scan on int8_tbl b
735+
Filter: ((q1 >= q2) AND (q1 <= q2))
736+
(4 rows)
737+
738+
select * from
739+
(select *, 0 as x from int8_tbl a
740+
union all
741+
select *, 1 as x from int8_tbl b) ss
742+
where (x = 0) or (q1 >= q2 and q1 <= q2);
743+
q1 | q2 | x
744+
------------------+-------------------+---
745+
123 | 456 | 0
746+
123 | 4567890123456789 | 0
747+
4567890123456789 | 123 | 0
748+
4567890123456789 | 4567890123456789 | 0
749+
4567890123456789 | -4567890123456789 | 0
750+
4567890123456789 | 4567890123456789 | 1
751+
(6 rows)
752+

src/test/regress/sql/union.sql

+13
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,16 @@ select * from
322322

323323
drop table t3;
324324
drop function expensivefunc(int);
325+
326+
-- Test handling of appendrel quals that const-simplify into an AND
327+
explain (costs off)
328+
select * from
329+
(select *, 0 as x from int8_tbl a
330+
union all
331+
select *, 1 as x from int8_tbl b) ss
332+
where (x = 0) or (q1 >= q2 and q1 <= q2);
333+
select * from
334+
(select *, 0 as x from int8_tbl a
335+
union all
336+
select *, 1 as x from int8_tbl b) ss
337+
where (x = 0) or (q1 >= q2 and q1 <= q2);

0 commit comments

Comments
 (0)