mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03: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:
		@@ -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,
 | 
				
			|||||||
				/* 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,
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				/* 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,
 | 
				
			|||||||
				/* 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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user