mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	Fix the way SJE removes references from PHVs
Add missing replacement of relids in phv->phexpr. Also, remove extra replace_relid() over phv->phrels. Reported-by: Zuming Jiang Bug: #18187 Discussion: https://postgr.es/m/flat/18187-831da249cbd2ff8e%40postgresql.org Author: Richard Guo Reviewed-by: Andrei Lepikhov
This commit is contained in:
		| @@ -474,9 +474,9 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel, | |||||||
| 			/* ph_needed might or might not become empty */ | 			/* ph_needed might or might not become empty */ | ||||||
| 			phv->phrels = replace_relid(phv->phrels, relid, subst); | 			phv->phrels = replace_relid(phv->phrels, relid, subst); | ||||||
| 			phv->phrels = replace_relid(phv->phrels, ojrelid, subst); | 			phv->phrels = replace_relid(phv->phrels, ojrelid, subst); | ||||||
| 			phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst); |  | ||||||
| 			phinfo->ph_var->phrels = replace_relid(phinfo->ph_var->phrels, relid, subst); |  | ||||||
| 			Assert(!bms_is_empty(phv->phrels)); | 			Assert(!bms_is_empty(phv->phrels)); | ||||||
|  | 			replace_varno((Node *) phv->phexpr, relid, subst); | ||||||
|  | 			phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst); | ||||||
| 			Assert(phv->phnullingrels == NULL); /* no need to adjust */ | 			Assert(phv->phnullingrels == NULL); /* no need to adjust */ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -6776,6 +6776,25 @@ SELECT c3.code FROM emp1 c3; | |||||||
|                ->  Seq Scan on emp1 c3 |                ->  Seq Scan on emp1 c3 | ||||||
| (7 rows) | (7 rows) | ||||||
|  |  | ||||||
|  | -- Check that SJE removes references from PHVs correctly | ||||||
|  | explain (costs off) | ||||||
|  | select * from emp1 t1 left join | ||||||
|  |     (select coalesce(t3.code, 1) from emp1 t2 | ||||||
|  |         left join (emp1 t3 join emp1 t4 on t3.id = t4.id) | ||||||
|  |         on true) | ||||||
|  | on true; | ||||||
|  |                      QUERY PLAN                      | ||||||
|  | ---------------------------------------------------- | ||||||
|  |  Nested Loop Left Join | ||||||
|  |    ->  Seq Scan on emp1 t1 | ||||||
|  |    ->  Materialize | ||||||
|  |          ->  Nested Loop Left Join | ||||||
|  |                ->  Seq Scan on emp1 t2 | ||||||
|  |                ->  Materialize | ||||||
|  |                      ->  Seq Scan on emp1 t4 | ||||||
|  |                            Filter: (id IS NOT NULL) | ||||||
|  | (8 rows) | ||||||
|  |  | ||||||
| -- We can remove the join even if we find the join can't duplicate rows and | -- We can remove the join even if we find the join can't duplicate rows and | ||||||
| -- the base quals of each side are different.  In the following case we end up | -- the base quals of each side are different.  In the following case we end up | ||||||
| -- moving quals over to s1 to make it so it can't match any rows. | -- moving quals over to s1 to make it so it can't match any rows. | ||||||
|   | |||||||
| @@ -2580,6 +2580,14 @@ WHERE c2.id IS NOT NULL | |||||||
| EXCEPT ALL | EXCEPT ALL | ||||||
| SELECT c3.code FROM emp1 c3; | SELECT c3.code FROM emp1 c3; | ||||||
|  |  | ||||||
|  | -- Check that SJE removes references from PHVs correctly | ||||||
|  | explain (costs off) | ||||||
|  | select * from emp1 t1 left join | ||||||
|  |     (select coalesce(t3.code, 1) from emp1 t2 | ||||||
|  |         left join (emp1 t3 join emp1 t4 on t3.id = t4.id) | ||||||
|  |         on true) | ||||||
|  | on true; | ||||||
|  |  | ||||||
| -- We can remove the join even if we find the join can't duplicate rows and | -- We can remove the join even if we find the join can't duplicate rows and | ||||||
| -- the base quals of each side are different.  In the following case we end up | -- the base quals of each side are different.  In the following case we end up | ||||||
| -- moving quals over to s1 to make it so it can't match any rows. | -- moving quals over to s1 to make it so it can't match any rows. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user