diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 56a5084..3c9d84f 100644
*** a/src/backend/optimizer/path/allpaths.c
--- b/src/backend/optimizer/path/allpaths.c
*************** set_append_rel_size(PlannerInfo *root, R
*** 1112,1122 ****
  		 * for partitioned child rels.
  		 *
  		 * Note: here we abuse the consider_partitionwise_join flag by setting
! 		 * it *even* for child rels that are not partitioned.  In that case,
! 		 * we set it to tell try_partitionwise_join() that it doesn't need to
! 		 * generate their targetlists and EC entries as they have already been
! 		 * generated here, as opposed to the dummy child rels for which the
! 		 * flag is left set to false so that it will generate them.
  		 */
  		if (rel->consider_partitionwise_join)
  			childrel->consider_partitionwise_join = true;
--- 1112,1122 ----
  		 * for partitioned child rels.
  		 *
  		 * Note: here we abuse the consider_partitionwise_join flag by setting
! 		 * it for child rels that are not themselves partitioned.  We do so to
! 		 * tell try_partitionwise_join() that the child rel is sufficiently
! 		 * valid to be used as a per-partition input, even if it later gets
! 		 * proven to be dummy.  (It's not usable until we've set up the
! 		 * reltarget and EC entries, which we just did.)
  		 */
  		if (rel->consider_partitionwise_join)
  			childrel->consider_partitionwise_join = true;
*************** generate_partitionwise_join_paths(Planne
*** 3564,3570 ****
  	{
  		RelOptInfo *child_rel = part_rels[cnt_parts];
  
! 		Assert(child_rel != NULL);
  
  		/* Add partitionwise join paths for partitioned child-joins. */
  		generate_partitionwise_join_paths(root, child_rel);
--- 3564,3572 ----
  	{
  		RelOptInfo *child_rel = part_rels[cnt_parts];
  
! 		/* If it's been pruned entirely, it's certainly dummy. */
! 		if (child_rel == NULL)
! 			continue;
  
  		/* Add partitionwise join paths for partitioned child-joins. */
  		generate_partitionwise_join_paths(root, child_rel);
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 9604a54..34cc7da 100644
*** a/src/backend/optimizer/path/joinrels.c
--- b/src/backend/optimizer/path/joinrels.c
***************
*** 15,23 ****
  #include "postgres.h"
  
  #include "miscadmin.h"
- #include "nodes/nodeFuncs.h"
  #include "optimizer/appendinfo.h"
- #include "optimizer/clauses.h"
  #include "optimizer/joininfo.h"
  #include "optimizer/pathnode.h"
  #include "optimizer/paths.h"
--- 15,21 ----
*************** static void try_partitionwise_join(Plann
*** 44,51 ****
  					   RelOptInfo *rel2, RelOptInfo *joinrel,
  					   SpecialJoinInfo *parent_sjinfo,
  					   List *parent_restrictlist);
- static void update_child_rel_info(PlannerInfo *root,
- 					  RelOptInfo *rel, RelOptInfo *childrel);
  static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
  						SpecialJoinInfo *parent_sjinfo,
  						Relids left_relids, Relids right_relids);
--- 42,47 ----
*************** try_partitionwise_join(PlannerInfo *root
*** 1405,1410 ****
--- 1401,1410 ----
  	{
  		RelOptInfo *child_rel1 = rel1->part_rels[cnt_parts];
  		RelOptInfo *child_rel2 = rel2->part_rels[cnt_parts];
+ 		bool		rel1_empty = (child_rel1 == NULL ||
+ 								  IS_DUMMY_REL(child_rel1));
+ 		bool		rel2_empty = (child_rel2 == NULL ||
+ 								  IS_DUMMY_REL(child_rel2));
  		SpecialJoinInfo *child_sjinfo;
  		List	   *child_restrictlist;
  		RelOptInfo *child_joinrel;
*************** try_partitionwise_join(PlannerInfo *root
*** 1413,1436 ****
  		int			nappinfos;
  
  		/*
! 		 * If a child table has consider_partitionwise_join=false, it means
  		 * that it's a dummy relation for which we skipped setting up tlist
! 		 * expressions and adding EC members in set_append_rel_size(), so do
! 		 * that now for use later.
  		 */
  		if (rel1_is_simple && !child_rel1->consider_partitionwise_join)
  		{
  			Assert(child_rel1->reloptkind == RELOPT_OTHER_MEMBER_REL);
  			Assert(IS_DUMMY_REL(child_rel1));
! 			update_child_rel_info(root, rel1, child_rel1);
! 			child_rel1->consider_partitionwise_join = true;
  		}
  		if (rel2_is_simple && !child_rel2->consider_partitionwise_join)
  		{
  			Assert(child_rel2->reloptkind == RELOPT_OTHER_MEMBER_REL);
  			Assert(IS_DUMMY_REL(child_rel2));
! 			update_child_rel_info(root, rel2, child_rel2);
! 			child_rel2->consider_partitionwise_join = true;
  		}
  
  		/* We should never try to join two overlapping sets of rels. */
--- 1413,1481 ----
  		int			nappinfos;
  
  		/*
! 		 * Check for cases where we can prove that this segment of the join
! 		 * returns no rows, due to one or both inputs being empty (including
! 		 * inputs that have been pruned away entirely).  If so just ignore it.
! 		 * These rules are equivalent to populate_joinrel_with_paths's rules
! 		 * for dummy input relations.
! 		 */
! 		switch (parent_sjinfo->jointype)
! 		{
! 			case JOIN_INNER:
! 			case JOIN_SEMI:
! 				if (rel1_empty || rel2_empty)
! 					continue;	/* ignore this join segment */
! 				break;
! 			case JOIN_LEFT:
! 			case JOIN_ANTI:
! 				if (rel1_empty)
! 					continue;	/* ignore this join segment */
! 				break;
! 			case JOIN_FULL:
! 				if (rel1_empty && rel2_empty)
! 					continue;	/* ignore this join segment */
! 				break;
! 			default:
! 				/* other values not expected here */
! 				elog(ERROR, "unrecognized join type: %d",
! 					 (int) parent_sjinfo->jointype);
! 				break;
! 		}
! 
! 		/*
! 		 * If a child has been pruned entirely then we can't generate paths
! 		 * for it, so we have to reject partitionwise joining unless we were
! 		 * able to eliminate this partition above.
! 		 */
! 		if (child_rel1 == NULL || child_rel2 == NULL)
! 		{
! 			/*
! 			 * Mark the joinrel as unpartitioned so that later functions treat
! 			 * it correctly.
! 			 */
! 			joinrel->nparts = 0;
! 			return;
! 		}
! 
! 		/*
! 		 * If a leaf relation has consider_partitionwise_join=false, it means
  		 * that it's a dummy relation for which we skipped setting up tlist
! 		 * expressions and adding EC members in set_append_rel_size(), so
! 		 * again we have to fail here.
  		 */
  		if (rel1_is_simple && !child_rel1->consider_partitionwise_join)
  		{
  			Assert(child_rel1->reloptkind == RELOPT_OTHER_MEMBER_REL);
  			Assert(IS_DUMMY_REL(child_rel1));
! 			joinrel->nparts = 0;
! 			return;
  		}
  		if (rel2_is_simple && !child_rel2->consider_partitionwise_join)
  		{
  			Assert(child_rel2->reloptkind == RELOPT_OTHER_MEMBER_REL);
  			Assert(IS_DUMMY_REL(child_rel2));
! 			joinrel->nparts = 0;
! 			return;
  		}
  
  		/* We should never try to join two overlapping sets of rels. */
*************** try_partitionwise_join(PlannerInfo *root
*** 1475,1502 ****
  }
  
  /*
-  * Set up tlist expressions for the childrel, and add EC members referencing
-  * the childrel.
-  */
- static void
- update_child_rel_info(PlannerInfo *root,
- 					  RelOptInfo *rel, RelOptInfo *childrel)
- {
- 	AppendRelInfo *appinfo = root->append_rel_array[childrel->relid];
- 
- 	/* Make child tlist expressions */
- 	childrel->reltarget->exprs = (List *)
- 		adjust_appendrel_attrs(root,
- 							   (Node *) rel->reltarget->exprs,
- 							   1, &appinfo);
- 
- 	/* Make child entries in the EquivalenceClass as well */
- 	if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
- 		add_child_rel_equivalences(root, appinfo, rel, childrel);
- 	childrel->has_eclass_joins = rel->has_eclass_joins;
- }
- 
- /*
   * Construct the SpecialJoinInfo for a child-join by translating
   * SpecialJoinInfo for the join between parents. left_relids and right_relids
   * are the relids of left and right side of the join respectively.
--- 1520,1525 ----
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index ca7a0fb..031e709 100644
*** a/src/backend/optimizer/plan/planner.c
--- b/src/backend/optimizer/plan/planner.c
*************** apply_scanjoin_target_to_paths(PlannerIn
*** 6993,6998 ****
--- 6993,7002 ----
  			List	   *child_scanjoin_targets = NIL;
  			ListCell   *lc;
  
+ 			/* Pruned or dummy children can be ignored. */
+ 			if (child_rel == NULL || IS_DUMMY_REL(child_rel))
+ 				continue;
+ 
  			/* Translate scan/join targets for this child. */
  			appinfos = find_appinfos_by_relids(root, child_rel->relids,
  											   &nappinfos);
*************** create_partitionwise_grouping_paths(Plan
*** 7093,7100 ****
  		RelOptInfo *child_grouped_rel;
  		RelOptInfo *child_partially_grouped_rel;
  
! 		/* Input child rel must have a path */
! 		Assert(child_input_rel->pathlist != NIL);
  
  		/*
  		 * Copy the given "extra" structure as is and then override the
--- 7097,7105 ----
  		RelOptInfo *child_grouped_rel;
  		RelOptInfo *child_partially_grouped_rel;
  
! 		/* Pruned or dummy children can be ignored. */
! 		if (child_input_rel == NULL || IS_DUMMY_REL(child_input_rel))
! 			continue;
  
  		/*
  		 * Copy the given "extra" structure as is and then override the
*************** create_partitionwise_grouping_paths(Plan
*** 7136,7149 ****
  											  extra->target_parallel_safe,
  											  child_extra.havingQual);
  
- 		/* Ignore empty children. They contribute nothing. */
- 		if (IS_DUMMY_REL(child_input_rel))
- 		{
- 			mark_dummy_rel(child_grouped_rel);
- 
- 			continue;
- 		}
- 
  		/* Create grouping paths for this child relation. */
  		create_ordinary_grouping_paths(root, child_input_rel,
  									   child_grouped_rel,
--- 7141,7146 ----
diff --git a/src/test/regress/expected/partition_aggregate.out b/src/test/regress/expected/partition_aggregate.out
index 6bc1068..9783281 100644
*** a/src/test/regress/expected/partition_aggregate.out
--- b/src/test/regress/expected/partition_aggregate.out
*************** SELECT a.x, sum(b.x) FROM pagg_tab1 a FU
*** 721,752 ****
  -- non-nullable columns
  EXPLAIN (COSTS OFF)
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
!                                  QUERY PLAN                                  
! -----------------------------------------------------------------------------
   Sort
!    Sort Key: pagg_tab1_p1.x, y
!    ->  Append
!          ->  HashAggregate
!                Group Key: pagg_tab1_p1.x, y
!                ->  Hash Left Join
!                      Hash Cond: (pagg_tab1_p1.x = y)
!                      Filter: ((pagg_tab1_p1.x > 5) OR (y < 20))
                       ->  Seq Scan on pagg_tab1_p1
                             Filter: (x < 20)
-                      ->  Hash
-                            ->  Result
-                                  One-Time Filter: false
-          ->  HashAggregate
-                Group Key: pagg_tab1_p2.x, pagg_tab2_p2.y
-                ->  Hash Left Join
-                      Hash Cond: (pagg_tab1_p2.x = pagg_tab2_p2.y)
-                      Filter: ((pagg_tab1_p2.x > 5) OR (pagg_tab2_p2.y < 20))
                       ->  Seq Scan on pagg_tab1_p2
                             Filter: (x < 20)
!                      ->  Hash
                             ->  Seq Scan on pagg_tab2_p2
                                   Filter: (y > 10)
! (23 rows)
  
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
   x  | y  | count 
--- 721,747 ----
  -- non-nullable columns
  EXPLAIN (COSTS OFF)
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
!                               QUERY PLAN                               
! -----------------------------------------------------------------------
   Sort
!    Sort Key: pagg_tab1_p1.x, pagg_tab2_p2.y
!    ->  HashAggregate
!          Group Key: pagg_tab1_p1.x, pagg_tab2_p2.y
!          ->  Hash Left Join
!                Hash Cond: (pagg_tab1_p1.x = pagg_tab2_p2.y)
!                Filter: ((pagg_tab1_p1.x > 5) OR (pagg_tab2_p2.y < 20))
!                ->  Append
                       ->  Seq Scan on pagg_tab1_p1
                             Filter: (x < 20)
                       ->  Seq Scan on pagg_tab1_p2
                             Filter: (x < 20)
!                ->  Hash
!                      ->  Append
                             ->  Seq Scan on pagg_tab2_p2
                                   Filter: (y > 10)
!                            ->  Seq Scan on pagg_tab2_p3
!                                  Filter: (y > 10)
! (18 rows)
  
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
   x  | y  | count 
*************** SELECT a.x, b.y, count(*) FROM (SELECT *
*** 765,808 ****
  -- nullable columns
  EXPLAIN (COSTS OFF)
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
!                                     QUERY PLAN                                     
! -----------------------------------------------------------------------------------
!  Finalize GroupAggregate
!    Group Key: pagg_tab1_p1.x, y
!    ->  Sort
!          Sort Key: pagg_tab1_p1.x, y
!          ->  Append
!                ->  Partial HashAggregate
!                      Group Key: pagg_tab1_p1.x, y
!                      ->  Hash Full Join
!                            Hash Cond: (pagg_tab1_p1.x = y)
!                            Filter: ((pagg_tab1_p1.x > 5) OR (y < 20))
!                            ->  Seq Scan on pagg_tab1_p1
!                                  Filter: (x < 20)
!                            ->  Hash
!                                  ->  Result
!                                        One-Time Filter: false
!                ->  Partial HashAggregate
!                      Group Key: pagg_tab1_p2.x, pagg_tab2_p2.y
!                      ->  Hash Full Join
!                            Hash Cond: (pagg_tab1_p2.x = pagg_tab2_p2.y)
!                            Filter: ((pagg_tab1_p2.x > 5) OR (pagg_tab2_p2.y < 20))
!                            ->  Seq Scan on pagg_tab1_p2
!                                  Filter: (x < 20)
!                            ->  Hash
!                                  ->  Seq Scan on pagg_tab2_p2
!                                        Filter: (y > 10)
!                ->  Partial HashAggregate
!                      Group Key: x, pagg_tab2_p3.y
!                      ->  Hash Full Join
!                            Hash Cond: (pagg_tab2_p3.y = x)
!                            Filter: ((x > 5) OR (pagg_tab2_p3.y < 20))
                             ->  Seq Scan on pagg_tab2_p3
                                   Filter: (y > 10)
!                            ->  Hash
!                                  ->  Result
!                                        One-Time Filter: false
! (35 rows)
  
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
   x  | y  | count 
--- 760,786 ----
  -- nullable columns
  EXPLAIN (COSTS OFF)
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20  GROUP BY a.x, b.y ORDER BY 1, 2;
!                               QUERY PLAN                               
! -----------------------------------------------------------------------
!  Sort
!    Sort Key: pagg_tab1_p1.x, pagg_tab2_p2.y
!    ->  HashAggregate
!          Group Key: pagg_tab1_p1.x, pagg_tab2_p2.y
!          ->  Hash Full Join
!                Hash Cond: (pagg_tab1_p1.x = pagg_tab2_p2.y)
!                Filter: ((pagg_tab1_p1.x > 5) OR (pagg_tab2_p2.y < 20))
!                ->  Append
!                      ->  Seq Scan on pagg_tab1_p1
!                            Filter: (x < 20)
!                      ->  Seq Scan on pagg_tab1_p2
!                            Filter: (x < 20)
!                ->  Hash
!                      ->  Append
!                            ->  Seq Scan on pagg_tab2_p2
!                                  Filter: (y > 10)
                             ->  Seq Scan on pagg_tab2_p3
                                   Filter: (y > 10)
! (18 rows)
  
  SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
   x  | y  | count 
diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out
index e19535d..e228e3f 100644
*** a/src/test/regress/expected/partition_join.out
--- b/src/test/regress/expected/partition_join.out
*************** SELECT t1.a, t1.c, t2.b, t2.c FROM (SELE
*** 210,232 ****
                          QUERY PLAN                         
  -----------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, b
!    ->  Append
!          ->  Hash Left Join
!                Hash Cond: (prt1_p1.a = b)
!                ->  Seq Scan on prt1_p1
!                      Filter: ((a < 450) AND (b = 0))
!                ->  Hash
!                      ->  Result
!                            One-Time Filter: false
!          ->  Hash Right Join
!                Hash Cond: (prt2_p2.b = prt1_p2.a)
                 ->  Seq Scan on prt2_p2
                       Filter: (b > 250)
!                ->  Hash
                       ->  Seq Scan on prt1_p2
                             Filter: ((a < 450) AND (b = 0))
! (17 rows)
  
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;
    a  |  c   |  b  |  c   
--- 210,230 ----
                          QUERY PLAN                         
  -----------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, prt2_p2.b
!    ->  Hash Right Join
!          Hash Cond: (prt2_p2.b = prt1_p1.a)
!          ->  Append
                 ->  Seq Scan on prt2_p2
                       Filter: (b > 250)
!                ->  Seq Scan on prt2_p3
!                      Filter: (b > 250)
!          ->  Hash
!                ->  Append
!                      ->  Seq Scan on prt1_p1
!                            Filter: ((a < 450) AND (b = 0))
                       ->  Seq Scan on prt1_p2
                             Filter: ((a < 450) AND (b = 0))
! (15 rows)
  
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;
    a  |  c   |  b  |  c   
*************** SELECT t1.a, t1.c, t2.b, t2.c FROM (SELE
*** 244,279 ****
  
  EXPLAIN (COSTS OFF)
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b;
!                          QUERY PLAN                         
! ------------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, b
!    ->  Append
!          ->  Hash Full Join
!                Hash Cond: (prt1_p1.a = b)
!                Filter: ((prt1_p1.b = 0) OR (a = 0))
                 ->  Seq Scan on prt1_p1
                       Filter: (a < 450)
-                ->  Hash
-                      ->  Result
-                            One-Time Filter: false
-          ->  Hash Full Join
-                Hash Cond: (prt1_p2.a = prt2_p2.b)
-                Filter: ((prt1_p2.b = 0) OR (prt2_p2.a = 0))
                 ->  Seq Scan on prt1_p2
                       Filter: (a < 450)
!                ->  Hash
                       ->  Seq Scan on prt2_p2
                             Filter: (b > 250)
!          ->  Hash Full Join
!                Hash Cond: (prt2_p3.b = a)
!                Filter: ((b = 0) OR (prt2_p3.a = 0))
!                ->  Seq Scan on prt2_p3
!                      Filter: (b > 250)
!                ->  Hash
!                      ->  Result
!                            One-Time Filter: false
! (27 rows)
  
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b;
    a  |  c   |  b  |  c   
--- 242,266 ----
  
  EXPLAIN (COSTS OFF)
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b;
!                       QUERY PLAN                      
! ------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, prt2_p2.b
!    ->  Hash Full Join
!          Hash Cond: (prt1_p1.a = prt2_p2.b)
!          Filter: ((prt1_p1.b = 0) OR (prt2_p2.a = 0))
!          ->  Append
                 ->  Seq Scan on prt1_p1
                       Filter: (a < 450)
                 ->  Seq Scan on prt1_p2
                       Filter: (a < 450)
!          ->  Hash
!                ->  Append
                       ->  Seq Scan on prt2_p2
                             Filter: (b > 250)
!                      ->  Seq Scan on prt2_p3
!                            Filter: (b > 250)
! (16 rows)
  
  SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b;
    a  |  c   |  b  |  c   
*************** SELECT t1.a, t2.b FROM (SELECT * FROM pr
*** 997,1025 ****
                          QUERY PLAN                         
  -----------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, b
!    ->  Append
!          ->  Merge Left Join
!                Merge Cond: (prt1_p1.a = b)
!                ->  Sort
!                      Sort Key: prt1_p1.a
                       ->  Seq Scan on prt1_p1
                             Filter: ((a < 450) AND (b = 0))
-                ->  Sort
-                      Sort Key: b
-                      ->  Result
-                            One-Time Filter: false
-          ->  Merge Left Join
-                Merge Cond: (prt1_p2.a = prt2_p2.b)
-                ->  Sort
-                      Sort Key: prt1_p2.a
                       ->  Seq Scan on prt1_p2
                             Filter: ((a < 450) AND (b = 0))
!                ->  Sort
!                      Sort Key: prt2_p2.b
                       ->  Seq Scan on prt2_p2
                             Filter: (b > 250)
! (23 rows)
  
  SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;
    a  |  b  
--- 984,1007 ----
                          QUERY PLAN                         
  -----------------------------------------------------------
   Sort
!    Sort Key: prt1_p1.a, prt2_p2.b
!    ->  Merge Left Join
!          Merge Cond: (prt1_p1.a = prt2_p2.b)
!          ->  Sort
!                Sort Key: prt1_p1.a
!                ->  Append
                       ->  Seq Scan on prt1_p1
                             Filter: ((a < 450) AND (b = 0))
                       ->  Seq Scan on prt1_p2
                             Filter: ((a < 450) AND (b = 0))
!          ->  Sort
!                Sort Key: prt2_p2.b
!                ->  Append
                       ->  Seq Scan on prt2_p2
                             Filter: (b > 250)
!                      ->  Seq Scan on prt2_p3
!                            Filter: (b > 250)
! (18 rows)
  
  SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;
    a  |  b  
