On Wed, Sep 20, 2017 at 3:13 PM, Ashutosh Bapat <
ashutosh.ba...@enterprisedb.com> wrote:

> On Wed, Sep 20, 2017 at 9:44 AM, Thomas Munro
> <thomas.mu...@enterprisedb.com> wrote:
> > 2.  What queries in the 0008 patch are hitting lines that 0007 doesn't
> hit?
> >
> > I thought about how to answer questions like this and came up with a
> > shell script that (1) makes computers run really hot for quite a long
> > time and (2) tells you which blocks of SQL hit which lines of C.
> > Please find attached the shell script and its output.  The .sql files
> > have been annotated with "block" numbers (blocks being chunks of SQL
> > stuff separated by blank lines), and the C files annotated with
> > references to those block numbers where A<n> = block <n>
> > partition_join.sql and B<n> = block <n> in partition_join_extras.sql.
> >
> > Then to find lines that B queries hit but A queries don't and know
> > which particular queries hit them, you might use something like:
> >
> >   grep -v 'SQL blocks: .*A[0-9]' < joinpath.c.aggregated_coverage | \
> >   grep 'SQL blocks: .*B[0-9]'
> >
>
> Thanks for this. It generates a lot of output (970 lines over all the
> coverage files). It will take some time for getting anything
> meaningful out of this. May be there's some faster way by looking at
> the lines that are covered by B but not A. BTW, I checked those lines
> to see if there could be any bug there. But I don't see what could go
> wrong with those lines.
>
> I have also tried to find test cases in B which hits some extra line which
is not
hitting by A, with the help of results attached by Thomas in
coverage.tarball_FILES.
It took lot of time but I am able to find some test cases. which if adding
in partition_join.sql
increasing no of lines hit by 14. but for hitting these 14 extra line
attached patch is doing
900+ line inserts in partition_join.sql and partition_join.out file.

I have used gcov-lcov to find coverage for files changed by
partition-wise-join patches
with and without attached patch which is below.


*with existing partition_join.sql* *partition_join.sql + some test cases of
partition_join_extra.sql*
*Modifed Files* *Line Coverage* *Functions* *Line Coverage* *Functions*
src/backend/optimizer/geqo 79.4 % 269/339 96.6 % 28/29 79.4 % 269/339 96.6 %
28/29
src/backend/optimizer/path/allpaths.c 92.3 % 787 / 853 95.5 % 42 / 44
92.6 % 790
/ 853 95.5 % 42 / 44
src/backend/optimizer/path/costsize.c 96.8 % 1415 / 1462 98.4 % 61 / 62
96.9 % 1416 / 1462 98.4 % 61 / 62
src/backend/optimizer/path/joinpath.c 95.5 % 404 / 423 100.0 % 16 / 16
95.5 % 404 / 423 100.0 % 16 / 16
src/backend/optimizer/path/joinrels.c 92.5 % 422 / 456 100.0 % 16 / 16
93.0 % 424 / 456 100.0 % 16 / 16
src/backend/optimizer/plan/createplan.c 90.9 % 1928 / 2122 96.3 % 103 / 107
91.0 % 1930 / 2122 96.3 % 103 / 107
src/backend/optimizer/plan/planner.c 94.9 % 1609 / 1696 97.6 % 41 / 42
94.9 % 1609 / 1696 97.6 % 41 / 42
src/backend/optimizer/plan/setrefs.c 91.3 % 806 / 883 94.3 % 33 / 35 91.3 % 806
/ 883 94.3 % 33 / 35
src/backend/optimizer/prep/prepunion.c 95.5 % 661 / 692 100.0 % 25 / 25
95.5 % 661 / 692 100.0 % 25 / 25
src/backend/optimizer/util/pathnode.c 88.7 % 1144 / 1290 98.1 % 52 / 53
88.8 % 1146 / 1290 98.1 % 52 / 53
src/backend/optimizer/util/placeholder.c 96.5 % 139 / 144 100.0 % 10 / 10
96.5 % 139 / 144 100.0 % 10 / 10
src/backend/optimizer/util/plancat.c 89.0 % 540 / 607 94.7 % 18 / 19 89.6 % 544
/ 607 94.7 % 18 / 19
src/backend/optimizer/util/relnode.c 95.3 % 548 / 575 100.0 % 24 / 24
95.3 % 548
/ 575 100.0 % 24 / 24
src/backend/utils/misc/guc.c 67.4 % 1536 / 2278 89.7 % 113 / 126 67.4 % 1536
/ 2278 89.7 % 113 / 126


Thanks & Regards,
Rajkumar Raghuwanshi
QMG, EnterpriseDB Corporation
diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out
index 9fec170..ab411b6 100644
--- a/src/test/regress/expected/partition_join.out
+++ b/src/test/regress/expected/partition_join.out
@@ -584,6 +584,215 @@ SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL
  550 |     | 
 (12 rows)
 
+-- join with aggregate
+EXPLAIN (VERBOSE, COSTS OFF)
+select t1.a, count(t2.*) from prt1 t1 left join prt1 t2 on (t1.a = t2.a) where t1.a % 25 = 0 group by t1.a;
+                          QUERY PLAN                           
+---------------------------------------------------------------
+ GroupAggregate
+   Output: t1.a, count(((t2.*)::prt1))
+   Group Key: t1.a
+   ->  Sort
+         Output: t1.a, ((t2.*)::prt1)
+         Sort Key: t1.a
+         ->  Append
+               ->  Hash Right Join
+                     Output: t1.a, ((t2.*)::prt1)
+                     Hash Cond: (t2.a = t1.a)
+                     ->  Seq Scan on public.prt1_p1 t2
+                           Output: t2.*, t2.a
+                     ->  Hash
+                           Output: t1.a
+                           ->  Seq Scan on public.prt1_p1 t1
+                                 Output: t1.a
+                                 Filter: ((t1.a % 25) = 0)
+               ->  Hash Right Join
+                     Output: t1_1.a, ((t2_1.*)::prt1)
+                     Hash Cond: (t2_1.a = t1_1.a)
+                     ->  Seq Scan on public.prt1_p2 t2_1
+                           Output: t2_1.*, t2_1.a
+                     ->  Hash
+                           Output: t1_1.a
+                           ->  Seq Scan on public.prt1_p2 t1_1
+                                 Output: t1_1.a
+                                 Filter: ((t1_1.a % 25) = 0)
+               ->  Hash Right Join
+                     Output: t1_2.a, ((t2_2.*)::prt1)
+                     Hash Cond: (t2_2.a = t1_2.a)
+                     ->  Seq Scan on public.prt1_p3 t2_2
+                           Output: t2_2.*, t2_2.a
+                     ->  Hash
+                           Output: t1_2.a
+                           ->  Seq Scan on public.prt1_p3 t1_2
+                                 Output: t1_2.a
+                                 Filter: ((t1_2.a % 25) = 0)
+(37 rows)
+
+select t1.a, count(t2.*) from prt1 t1 left join prt1 t2 on (t1.a = t2.a) where t1.a % 25 = 0 group by t1.a;
+  a  | count 
+-----+-------
+   0 |     1
+  50 |     1
+ 100 |     1
+ 150 |     1
+ 200 |     1
+ 250 |     1
+ 300 |     1
+ 350 |     1
+ 400 |     1
+ 450 |     1
+ 500 |     1
+ 550 |     1
+(12 rows)
+
+-- lateral with VALUES
+EXPLAIN (VERBOSE, COSTS OFF)
+select count(*) from prt1 a, prt2 b join lateral (values(a.a)) ss(x) on b.b = ss.x;
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Aggregate
+   Output: count(*)
+   ->  Append
+         ->  Hash Join
+               Hash Cond: (a.a = b.b)
+               ->  Seq Scan on public.prt1_p1 a
+                     Output: a.a
+               ->  Hash
+                     Output: b.b
+                     ->  Seq Scan on public.prt2_p1 b
+                           Output: b.b
+         ->  Hash Join
+               Hash Cond: (a_1.a = b_1.b)
+               ->  Seq Scan on public.prt1_p2 a_1
+                     Output: a_1.a
+               ->  Hash
+                     Output: b_1.b
+                     ->  Seq Scan on public.prt2_p2 b_1
+                           Output: b_1.b
+         ->  Hash Join
+               Hash Cond: (a_2.a = b_2.b)
+               ->  Seq Scan on public.prt1_p3 a_2
+                     Output: a_2.a
+               ->  Hash
+                     Output: b_2.b
+                     ->  Seq Scan on public.prt2_p3 b_2
+                           Output: b_2.b
+(27 rows)
+
+select count(*) from prt1 a, prt2 b join lateral (values(a.a)) ss(x) on b.b = ss.x;
+ count 
+-------
+   100
+(1 row)
+
+-- join with rank
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.b, t2.b,rank() OVER (ORDER BY t2.b DESC) FROM prt1 t1 inner join prt2 t2 on (t1.a = t2.b) where t1.a % 25 = 0 order by 1,2,3;
+                                QUERY PLAN                                 
+---------------------------------------------------------------------------
+ Sort
+   Output: t1.a, t1.b, t2.b, (rank() OVER (?))
+   Sort Key: t1.a, t1.b
+   ->  WindowAgg
+         Output: t1.a, t1.b, t2.b, rank() OVER (?)
+         ->  Sort
+               Output: t2.b, t1.a, t1.b
+               Sort Key: t2.b DESC
+               ->  Result
+                     Output: t2.b, t1.a, t1.b
+                     ->  Append
+                           ->  Hash Join
+                                 Output: t1.a, t1.b, t2.b
+                                 Hash Cond: (t2.b = t1.a)
+                                 ->  Seq Scan on public.prt2_p1 t2
+                                       Output: t2.b
+                                 ->  Hash
+                                       Output: t1.a, t1.b
+                                       ->  Seq Scan on public.prt1_p1 t1
+                                             Output: t1.a, t1.b
+                                             Filter: ((t1.a % 25) = 0)
+                           ->  Hash Join
+                                 Output: t1_1.a, t1_1.b, t2_1.b
+                                 Hash Cond: (t2_1.b = t1_1.a)
+                                 ->  Seq Scan on public.prt2_p2 t2_1
+                                       Output: t2_1.b
+                                 ->  Hash
+                                       Output: t1_1.a, t1_1.b
+                                       ->  Seq Scan on public.prt1_p2 t1_1
+                                             Output: t1_1.a, t1_1.b
+                                             Filter: ((t1_1.a % 25) = 0)
+                           ->  Hash Join
+                                 Output: t1_2.a, t1_2.b, t2_2.b
+                                 Hash Cond: (t2_2.b = t1_2.a)
+                                 ->  Seq Scan on public.prt2_p3 t2_2
+                                       Output: t2_2.b
+                                 ->  Hash
+                                       Output: t1_2.a, t1_2.b
+                                       ->  Seq Scan on public.prt1_p3 t1_2
+                                             Output: t1_2.a, t1_2.b
+                                             Filter: ((t1_2.a % 25) = 0)
+(41 rows)
+
+SELECT t1.a, t1.b, t2.b,rank() OVER (ORDER BY t2.b DESC) FROM prt1 t1 inner join prt2 t2 on (t1.a = t2.b) where t1.a % 25 = 0 order by 1,2,3;
+  a  | b |  b  | rank 
+-----+---+-----+------
+   0 | 0 |   0 |    4
+ 150 | 0 | 150 |    3
+ 300 | 0 | 300 |    2
+ 450 | 0 | 450 |    1
+(4 rows)
+
+--join with prepare statement
+PREPARE ij(int) AS select t1.a,t2.b from prt1 t1 inner join prt2 t2 on (t1.a = t2.b and t1.a % $1 = 0) ORDER BY 1,2;
+EXPLAIN (VERBOSE, COSTS OFF) EXECUTE ij(25);
+                       QUERY PLAN                        
+---------------------------------------------------------
+ Sort
+   Output: t1.a, t2.b
+   Sort Key: t1.a
+   ->  Append
+         ->  Hash Join
+               Output: t1.a, t2.b
+               Hash Cond: (t2.b = t1.a)
+               ->  Seq Scan on public.prt2_p1 t2
+                     Output: t2.b
+               ->  Hash
+                     Output: t1.a
+                     ->  Seq Scan on public.prt1_p1 t1
+                           Output: t1.a
+                           Filter: ((t1.a % 25) = 0)
+         ->  Hash Join
+               Output: t1_1.a, t2_1.b
+               Hash Cond: (t2_1.b = t1_1.a)
+               ->  Seq Scan on public.prt2_p2 t2_1
+                     Output: t2_1.b
+               ->  Hash
+                     Output: t1_1.a
+                     ->  Seq Scan on public.prt1_p2 t1_1
+                           Output: t1_1.a
+                           Filter: ((t1_1.a % 25) = 0)
+         ->  Hash Join
+               Output: t1_2.a, t2_2.b
+               Hash Cond: (t2_2.b = t1_2.a)
+               ->  Seq Scan on public.prt2_p3 t2_2
+                     Output: t2_2.b
+               ->  Hash
+                     Output: t1_2.a
+                     ->  Seq Scan on public.prt1_p3 t1_2
+                           Output: t1_2.a
+                           Filter: ((t1_2.a % 25) = 0)
+(34 rows)
+
+EXECUTE ij(25);
+  a  |  b  
+-----+-----
+   0 |   0
+ 150 | 150
+ 300 | 300
+ 450 | 450
+(4 rows)
+
+DEALLOCATE ij;
 --
 -- partitioned by expression
 --
@@ -1094,7 +1303,8 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2
                            ->  Seq Scan on prt2_p3 t2_2
 (52 rows)
 
-SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a,
+t2.b, t3.a + t3.b;
   a  |  c   |  b  |  c   | ?column? | c 
 -----+------+-----+------+----------+---
    0 | 0000 |   0 | 0000 |        0 | 0
@@ -1111,6 +1321,234 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2
  550 | 0550 |     |      |     1100 | 0
 (12 rows)
 
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.a %25 = 0)) AND t1.a % 25 = 0 ORDER BY t1.a;
+                                QUERY PLAN                                 
+---------------------------------------------------------------------------
+ Merge Append
+   Sort Key: t1.a
+   ->  Merge Semi Join
+         Output: t1.a, t1.b, t1.c
+         Merge Cond: (t1.a = t1_3.b)
+         ->  Sort
+               Output: t1.a, t1.b, t1.c
+               Sort Key: t1.a
+               ->  Seq Scan on public.prt1_p1 t1
+                     Output: t1.a, t1.b, t1.c
+                     Filter: ((t1.a % 25) = 0)
+         ->  Merge Semi Join
+               Output: t1_3.b, t1_6.a, t1_6.b
+               Merge Cond: (t1_3.b = (((t1_6.a + t1_6.b) / 2)))
+               ->  Sort
+                     Output: t1_3.b
+                     Sort Key: t1_3.b
+                     ->  Seq Scan on public.prt2_p1 t1_3
+                           Output: t1_3.b
+               ->  Sort
+                     Output: t1_6.a, t1_6.b, (((t1_6.a + t1_6.b) / 2))
+                     Sort Key: (((t1_6.a + t1_6.b) / 2))
+                     ->  Seq Scan on public.prt1_e_p1 t1_6
+                           Output: t1_6.a, t1_6.b, ((t1_6.a + t1_6.b) / 2)
+                           Filter: ((t1_6.a % 25) = 0)
+   ->  Merge Semi Join
+         Output: t1_1.a, t1_1.b, t1_1.c
+         Merge Cond: (t1_1.a = t1_4.b)
+         ->  Sort
+               Output: t1_1.a, t1_1.b, t1_1.c
+               Sort Key: t1_1.a
+               ->  Seq Scan on public.prt1_p2 t1_1
+                     Output: t1_1.a, t1_1.b, t1_1.c
+                     Filter: ((t1_1.a % 25) = 0)
+         ->  Merge Semi Join
+               Output: t1_4.b, t1_7.a, t1_7.b
+               Merge Cond: (t1_4.b = (((t1_7.a + t1_7.b) / 2)))
+               ->  Sort
+                     Output: t1_4.b
+                     Sort Key: t1_4.b
+                     ->  Seq Scan on public.prt2_p2 t1_4
+                           Output: t1_4.b
+               ->  Sort
+                     Output: t1_7.a, t1_7.b, (((t1_7.a + t1_7.b) / 2))
+                     Sort Key: (((t1_7.a + t1_7.b) / 2))
+                     ->  Seq Scan on public.prt1_e_p2 t1_7
+                           Output: t1_7.a, t1_7.b, ((t1_7.a + t1_7.b) / 2)
+                           Filter: ((t1_7.a % 25) = 0)
+   ->  Merge Semi Join
+         Output: t1_2.a, t1_2.b, t1_2.c
+         Merge Cond: (t1_2.a = t1_5.b)
+         ->  Sort
+               Output: t1_2.a, t1_2.b, t1_2.c
+               Sort Key: t1_2.a
+               ->  Seq Scan on public.prt1_p3 t1_2
+                     Output: t1_2.a, t1_2.b, t1_2.c
+                     Filter: ((t1_2.a % 25) = 0)
+         ->  Merge Semi Join
+               Output: t1_5.b, t1_8.a, t1_8.b
+               Merge Cond: (t1_5.b = (((t1_8.a + t1_8.b) / 2)))
+               ->  Sort
+                     Output: t1_5.b
+                     Sort Key: t1_5.b
+                     ->  Seq Scan on public.prt2_p3 t1_5
+                           Output: t1_5.b
+               ->  Sort
+                     Output: t1_8.a, t1_8.b, (((t1_8.a + t1_8.b) / 2))
+                     Sort Key: (((t1_8.a + t1_8.b) / 2))
+                     ->  Seq Scan on public.prt1_e_p3 t1_8
+                           Output: t1_8.a, t1_8.b, ((t1_8.a + t1_8.b) / 2)
+                           Filter: ((t1_8.a % 25) = 0)
+(71 rows)
+
+SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.a %25 = 0)) AND t1.a % 25 = 0 ORDER BY t1.a;
+  a  | b |  c   
+-----+---+------
+   0 | 0 | 0000
+ 150 | 0 | 0150
+ 300 | 0 | 0300
+ 450 | 0 | 0450
+(4 rows)
+
+SET enable_seqscan TO off;
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t2.b = (t3.a + t3.b)/2) WHERE t3.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+                                          QUERY PLAN                                          
+----------------------------------------------------------------------------------------------
+ Sort
+   Output: t1.a, t1.c, t2.b, t2.c, ((t3.a + t3.b)), t3.c
+   Sort Key: t1.a, t2.b, ((t3.a + t3.b))
+   ->  Result
+         Output: t1.a, t1.c, t2.b, t2.c, (t3.a + t3.b), t3.c
+         ->  Append
+               ->  Merge Left Join
+                     Output: t3.a, t3.b, t3.c, t2.b, t2.c, t1.a, t1.c
+                     Merge Cond: (t2.b = t1.a)
+                     ->  Sort
+                           Output: t3.a, t3.b, t3.c, t2.b, t2.c
+                           Sort Key: t2.b
+                           ->  Merge Left Join
+                                 Output: t3.a, t3.b, t3.c, t2.b, t2.c
+                                 Merge Cond: (((t3.a + t3.b) / 2) = t2.b)
+                                 ->  Index Scan using iprt1_e_p1_ab2 on public.prt1_e_p1 t3
+                                       Output: t3.a, t3.b, t3.c
+                                       Filter: ((t3.a % 25) = 0)
+                                 ->  Index Scan using iprt2_p1_b on public.prt2_p1 t2
+                                       Output: t2.b, t2.c
+                     ->  Index Scan using iprt1_p1_a on public.prt1_p1 t1
+                           Output: t1.a, t1.c
+               ->  Merge Left Join
+                     Output: t3_1.a, t3_1.b, t3_1.c, t2_1.b, t2_1.c, t1_1.a, t1_1.c
+                     Merge Cond: (t2_1.b = t1_1.a)
+                     ->  Sort
+                           Output: t3_1.a, t3_1.b, t3_1.c, t2_1.b, t2_1.c
+                           Sort Key: t2_1.b
+                           ->  Merge Left Join
+                                 Output: t3_1.a, t3_1.b, t3_1.c, t2_1.b, t2_1.c
+                                 Merge Cond: (((t3_1.a + t3_1.b) / 2) = t2_1.b)
+                                 ->  Index Scan using iprt1_e_p2_ab2 on public.prt1_e_p2 t3_1
+                                       Output: t3_1.a, t3_1.b, t3_1.c
+                                       Filter: ((t3_1.a % 25) = 0)
+                                 ->  Index Scan using iprt2_p2_b on public.prt2_p2 t2_1
+                                       Output: t2_1.b, t2_1.c
+                     ->  Index Scan using iprt1_p2_a on public.prt1_p2 t1_1
+                           Output: t1_1.a, t1_1.c
+               ->  Merge Right Join
+                     Output: t3_2.a, t3_2.b, t3_2.c, t2_2.b, t2_2.c, t1_2.a, t1_2.c
+                     Merge Cond: (t2_2.b = ((t3_2.a + t3_2.b) / 2))
+                     ->  Merge Left Join
+                           Output: t2_2.b, t2_2.c, t1_2.a, t1_2.c
+                           Merge Cond: (t2_2.b = t1_2.a)
+                           ->  Index Scan using iprt2_p3_b on public.prt2_p3 t2_2
+                                 Output: t2_2.b, t2_2.c
+                           ->  Index Scan using iprt1_p3_a on public.prt1_p3 t1_2
+                                 Output: t1_2.a, t1_2.c
+                     ->  Index Scan using iprt1_e_p3_ab2 on public.prt1_e_p3 t3_2
+                           Output: t3_2.a, t3_2.b, t3_2.c
+                           Filter: ((t3_2.a % 25) = 0)
+(51 rows)
+
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t2.b = (t3.a + t3.b)/2) WHERE t3.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+  a  |  c   |  b  |  c   | ?column? | c 
+-----+------+-----+------+----------+---
+   0 | 0000 |   0 | 0000 |        0 | 0
+ 150 | 0150 | 150 | 0150 |      300 | 0
+ 300 | 0300 | 300 | 0300 |      600 | 0
+ 450 | 0450 | 450 | 0450 |      900 | 0
+     |      |     |      |      100 | 0
+     |      |     |      |      200 | 0
+     |      |     |      |      400 | 0
+     |      |     |      |      500 | 0
+     |      |     |      |      700 | 0
+     |      |     |      |      800 | 0
+     |      |     |      |     1000 | 0
+     |      |     |      |     1100 | 0
+(12 rows)
+
+-- lateral references and parameterized paths
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM prt1 t1 LEFT JOIN LATERAL
+(SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
+ON t1.a = ss.t2a WHERE t1.a % 25 = 0 ORDER BY t1.a;
+                                QUERY PLAN                                 
+---------------------------------------------------------------------------
+ Nested Loop Left Join
+   Output: t1.a, t1.b, t1.c, t2.a, t3.a, (LEAST(t1.a, t2.a, t3.a)), t1.a
+   ->  Merge Append
+         Sort Key: t1.a
+         ->  Index Scan using iprt1_p1_a on public.prt1_p1 t1
+               Output: t1.a, t1.b, t1.c
+               Filter: ((t1.a % 25) = 0)
+         ->  Index Scan using iprt1_p2_a on public.prt1_p2 t1_1
+               Output: t1_1.a, t1_1.b, t1_1.c
+               Filter: ((t1_1.a % 25) = 0)
+         ->  Index Scan using iprt1_p3_a on public.prt1_p3 t1_2
+               Output: t1_2.a, t1_2.b, t1_2.c
+               Filter: ((t1_2.a % 25) = 0)
+   ->  Append
+         ->  Merge Join
+               Output: t2.a, t3.a, LEAST(t1.a, t2.a, t3.a)
+               Merge Cond: (t2.a = t3.b)
+               ->  Index Only Scan using iprt1_p1_a on public.prt1_p1 t2
+                     Output: t2.a
+                     Index Cond: (t2.a = t1.a)
+               ->  Index Scan using iprt2_p1_b on public.prt2_p1 t3
+                     Output: t3.a, t3.b
+         ->  Merge Join
+               Output: t2_1.a, t3_1.a, LEAST(t1.a, t2_1.a, t3_1.a)
+               Merge Cond: (t2_1.a = t3_1.b)
+               ->  Index Only Scan using iprt1_p2_a on public.prt1_p2 t2_1
+                     Output: t2_1.a
+                     Index Cond: (t2_1.a = t1.a)
+               ->  Index Scan using iprt2_p2_b on public.prt2_p2 t3_1
+                     Output: t3_1.a, t3_1.b
+         ->  Merge Join
+               Output: t2_2.a, t3_2.a, LEAST(t1.a, t2_2.a, t3_2.a)
+               Merge Cond: (t2_2.a = t3_2.b)
+               ->  Index Only Scan using iprt1_p3_a on public.prt1_p3 t2_2
+                     Output: t2_2.a
+                     Index Cond: (t2_2.a = t1.a)
+               ->  Index Scan using iprt2_p3_b on public.prt2_p3 t3_2
+                     Output: t3_2.a, t3_2.b
+(38 rows)
+
+SELECT * FROM prt1 t1 LEFT JOIN LATERAL
+(SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
+ON t1.a = ss.t2a WHERE t1.a % 25 = 0 ORDER BY t1.a;
+  a  | b |  c   | t2a | t3a | least 
+-----+---+------+-----+-----+-------
+   0 | 0 | 0000 |   0 |   0 |     0
+  50 | 0 | 0050 |     |     |      
+ 100 | 0 | 0100 |     |     |      
+ 150 | 0 | 0150 | 150 |   0 |     0
+ 200 | 0 | 0200 |     |     |      
+ 250 | 0 | 0250 |     |     |      
+ 300 | 0 | 0300 | 300 |   0 |     0
+ 350 | 0 | 0350 |     |     |      
+ 400 | 0 | 0400 |     |     |      
+ 450 | 0 | 0450 | 450 |   0 |     0
+ 500 | 0 | 0500 |     |     |      
+ 550 | 0 | 0550 |     |     |      
+(12 rows)
+
+RESET enable_seqscan;
 -- MergeAppend on nullable column
 EXPLAIN (COSTS OFF)
 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;
@@ -1238,6 +1676,187 @@ CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0
 CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011');
 INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i;
 ANALYZE plt2;
+--full join using
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM plt1 t1 FULL JOIN plt2 t2 USING (c) FULL JOIN plt1 t3 USING (c)
+where t1.a %150 =0 and t2.b % 150 = 0 and t3.a % 150 = 0 order by 1,2,3;
+                                        QUERY PLAN                                        
+------------------------------------------------------------------------------------------
+ Sort
+   Output: (COALESCE(COALESCE(t1.c, t2.c), t3.c)), t1.a, t1.b, t2.a, t2.b, t3.a, t3.b
+   Sort Key: (COALESCE(COALESCE(t1.c, t2.c), t3.c)), t1.a, t1.b
+   ->  Nested Loop
+         Output: COALESCE(COALESCE(t1.c, t2.c), t3.c), t1.a, t1.b, t2.a, t2.b, t3.a, t3.b
+         Join Filter: (COALESCE(t1.c, t2.c) = t3.c)
+         ->  Nested Loop
+               Output: t1.c, t1.a, t1.b, t2.c, t2.a, t2.b
+               Join Filter: (t1.c = t2.c)
+               ->  Append
+                     ->  Seq Scan on public.plt1_p1 t1
+                           Output: t1.c, t1.a, t1.b
+                           Filter: ((t1.a % 150) = 0)
+                     ->  Seq Scan on public.plt1_p2 t1_1
+                           Output: t1_1.c, t1_1.a, t1_1.b
+                           Filter: ((t1_1.a % 150) = 0)
+                     ->  Seq Scan on public.plt1_p3 t1_2
+                           Output: t1_2.c, t1_2.a, t1_2.b
+                           Filter: ((t1_2.a % 150) = 0)
+               ->  Materialize
+                     Output: t2.c, t2.a, t2.b
+                     ->  Append
+                           ->  Seq Scan on public.plt2_p1 t2
+                                 Output: t2.c, t2.a, t2.b
+                                 Filter: ((t2.b % 150) = 0)
+                           ->  Seq Scan on public.plt2_p2 t2_1
+                                 Output: t2_1.c, t2_1.a, t2_1.b
+                                 Filter: ((t2_1.b % 150) = 0)
+                           ->  Seq Scan on public.plt2_p3 t2_2
+                                 Output: t2_2.c, t2_2.a, t2_2.b
+                                 Filter: ((t2_2.b % 150) = 0)
+         ->  Append
+               ->  Seq Scan on public.plt1_p1 t3
+                     Output: t3.c, t3.a, t3.b
+                     Filter: ((t3.a % 150) = 0)
+               ->  Seq Scan on public.plt1_p2 t3_1
+                     Output: t3_1.c, t3_1.a, t3_1.b
+                     Filter: ((t3_1.a % 150) = 0)
+               ->  Seq Scan on public.plt1_p3 t3_2
+                     Output: t3_2.c, t3_2.a, t3_2.b
+                     Filter: ((t3_2.a % 150) = 0)
+(41 rows)
+
+SELECT * FROM plt1 t1 FULL JOIN plt2 t2 USING (c) FULL JOIN plt1 t3 USING (c)
+where t1.a %150 =0 and t2.b % 150 = 0 and t3.a % 150 = 0 order by 1,2,3;
+  c   |  a  |  b  |  a  |  b  |  a  |  b  
+------+-----+-----+-----+-----+-----+-----
+ 0000 |   0 |   0 |   0 |   0 |   0 |   0
+ 0003 | 150 | 150 | 150 | 150 | 150 | 150
+ 0006 | 300 | 300 | 300 | 300 | 300 | 300
+ 0009 | 450 | 450 | 450 | 450 | 450 | 450
+(4 rows)
+
+-- test placement of movable quals in a parameterized join tree
+EXPLAIN (VERBOSE, COSTS OFF)
+select b.b from prt1 a join prt2 b on a.a = b.b left join plt1 c on b.a % 25 = 0 and c.c = a.c join prt1 i1 on b.b = i1.a
+right join prt2 i2 on i2.b = b.b where b.a % 25 = 0 order by 1;
+                                      QUERY PLAN                                       
+---------------------------------------------------------------------------------------
+ Sort
+   Output: b.b
+   Sort Key: b.b
+   ->  Hash Right Join
+         Output: b.b
+         Hash Cond: (c.c = (a.c)::text)
+         Join Filter: ((b.a % 25) = 0)
+         ->  Append
+               ->  Seq Scan on public.plt1_p1 c
+                     Output: c.c
+               ->  Seq Scan on public.plt1_p2 c_1
+                     Output: c_1.c
+               ->  Seq Scan on public.plt1_p3 c_2
+                     Output: c_2.c
+         ->  Hash
+               Output: a.c, b.b, b.a
+               ->  Append
+                     ->  Nested Loop
+                           Output: a.c, b.b, b.a
+                           ->  Nested Loop
+                                 Output: a.a, a.c, b.b, b.a, i2.b
+                                 Join Filter: (b.b = a.a)
+                                 ->  Hash Join
+                                       Output: b.b, b.a, i2.b
+                                       Hash Cond: (i2.b = b.b)
+                                       ->  Seq Scan on public.prt2_p1 i2
+                                             Output: i2.b
+                                       ->  Hash
+                                             Output: b.b, b.a
+                                             ->  Seq Scan on public.prt2_p1 b
+                                                   Output: b.b, b.a
+                                                   Filter: ((b.a % 25) = 0)
+                                 ->  Index Scan using iprt1_p1_a on public.prt1_p1 a
+                                       Output: a.a, a.c
+                                       Index Cond: (a.a = i2.b)
+                           ->  Index Only Scan using iprt1_p1_a on public.prt1_p1 i1
+                                 Output: i1.a
+                                 Index Cond: (i1.a = a.a)
+                     ->  Nested Loop
+                           Output: a_1.c, b_1.b, b_1.a
+                           ->  Nested Loop
+                                 Output: a_1.a, a_1.c, b_1.b, b_1.a, i2_1.b
+                                 Join Filter: (b_1.b = a_1.a)
+                                 ->  Hash Join
+                                       Output: b_1.b, b_1.a, i2_1.b
+                                       Hash Cond: (i2_1.b = b_1.b)
+                                       ->  Seq Scan on public.prt2_p2 i2_1
+                                             Output: i2_1.b
+                                       ->  Hash
+                                             Output: b_1.b, b_1.a
+                                             ->  Seq Scan on public.prt2_p2 b_1
+                                                   Output: b_1.b, b_1.a
+                                                   Filter: ((b_1.a % 25) = 0)
+                                 ->  Index Scan using iprt1_p2_a on public.prt1_p2 a_1
+                                       Output: a_1.a, a_1.c
+                                       Index Cond: (a_1.a = i2_1.b)
+                           ->  Index Only Scan using iprt1_p2_a on public.prt1_p2 i1_1
+                                 Output: i1_1.a
+                                 Index Cond: (i1_1.a = a_1.a)
+                     ->  Nested Loop
+                           Output: a_2.c, b_2.b, b_2.a
+                           ->  Nested Loop
+                                 Output: a_2.a, a_2.c, b_2.b, b_2.a, i2_2.b
+                                 Join Filter: (b_2.b = a_2.a)
+                                 ->  Hash Join
+                                       Output: b_2.b, b_2.a, i2_2.b
+                                       Hash Cond: (i2_2.b = b_2.b)
+                                       ->  Seq Scan on public.prt2_p3 i2_2
+                                             Output: i2_2.b
+                                       ->  Hash
+                                             Output: b_2.b, b_2.a
+                                             ->  Seq Scan on public.prt2_p3 b_2
+                                                   Output: b_2.b, b_2.a
+                                                   Filter: ((b_2.a % 25) = 0)
+                                 ->  Index Scan using iprt1_p3_a on public.prt1_p3 a_2
+                                       Output: a_2.a, a_2.c
+                                       Index Cond: (a_2.a = i2_2.b)
+                           ->  Index Only Scan using iprt1_p3_a on public.prt1_p3 i1_2
+                                 Output: i1_2.a
+                                 Index Cond: (i1_2.a = a_2.a)
+(80 rows)
+
+select b.b from prt1 a join prt2 b on a.a = b.b left join plt1 c on b.a % 25 = 0 and c.c = a.c join prt1 i1 on b.b = i1.a
+right join prt2 i2 on i2.b = b.b where b.a % 25 = 0 order by 1;
+  b  
+-----
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+   0
+ 150
+ 300
+ 450
+(28 rows)
+
 --
 -- list partitioned by expression
 --
@@ -1304,6 +1923,86 @@ SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, pl
  574.0000000000000000 | 574.5000000000000000 | 1148.0000000000000000 | 0011 | 0011 | A0011
 (12 rows)
 
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (plt1 t1 LEFT JOIN plt2 t2 ON t1.a = t2.b AND t1.c = t2.c) LEFT JOIN plt1_e t3 ON (t2.b = t3.a AND t2.c = ltrim(t3.c, 'A')) WHERE t1.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+                                         QUERY PLAN                                         
+--------------------------------------------------------------------------------------------
+ Sort
+   Output: t1.a, t1.c, t2.b, t2.c, ((t3.a + t3.b)), t3.c
+   Sort Key: t1.a, t2.b, ((t3.a + t3.b))
+   ->  Result
+         Output: t1.a, t1.c, t2.b, t2.c, (t3.a + t3.b), t3.c
+         ->  Append
+               ->  Hash Right Join
+                     Output: t1.a, t1.c, t2.b, t2.c, t3.a, t3.b, t3.c
+                     Hash Cond: ((t3.a = t2.b) AND (ltrim(t3.c, 'A'::text) = t2.c))
+                     ->  Seq Scan on public.plt1_e_p1 t3
+                           Output: t3.a, t3.b, t3.c
+                     ->  Hash
+                           Output: t1.a, t1.c, t2.b, t2.c
+                           ->  Hash Right Join
+                                 Output: t1.a, t1.c, t2.b, t2.c
+                                 Hash Cond: ((t2.b = t1.a) AND (t2.c = t1.c))
+                                 ->  Seq Scan on public.plt2_p1 t2
+                                       Output: t2.b, t2.c
+                                 ->  Hash
+                                       Output: t1.a, t1.c
+                                       ->  Seq Scan on public.plt1_p1 t1
+                                             Output: t1.a, t1.c
+                                             Filter: ((t1.a % 25) = 0)
+               ->  Hash Right Join
+                     Output: t1_1.a, t1_1.c, t2_1.b, t2_1.c, t3_1.a, t3_1.b, t3_1.c
+                     Hash Cond: ((t3_1.a = t2_1.b) AND (ltrim(t3_1.c, 'A'::text) = t2_1.c))
+                     ->  Seq Scan on public.plt1_e_p2 t3_1
+                           Output: t3_1.a, t3_1.b, t3_1.c
+                     ->  Hash
+                           Output: t1_1.a, t1_1.c, t2_1.b, t2_1.c
+                           ->  Hash Right Join
+                                 Output: t1_1.a, t1_1.c, t2_1.b, t2_1.c
+                                 Hash Cond: ((t2_1.b = t1_1.a) AND (t2_1.c = t1_1.c))
+                                 ->  Seq Scan on public.plt2_p2 t2_1
+                                       Output: t2_1.b, t2_1.c
+                                 ->  Hash
+                                       Output: t1_1.a, t1_1.c
+                                       ->  Seq Scan on public.plt1_p2 t1_1
+                                             Output: t1_1.a, t1_1.c
+                                             Filter: ((t1_1.a % 25) = 0)
+               ->  Hash Right Join
+                     Output: t1_2.a, t1_2.c, t2_2.b, t2_2.c, t3_2.a, t3_2.b, t3_2.c
+                     Hash Cond: ((t3_2.a = t2_2.b) AND (ltrim(t3_2.c, 'A'::text) = t2_2.c))
+                     ->  Seq Scan on public.plt1_e_p3 t3_2
+                           Output: t3_2.a, t3_2.b, t3_2.c
+                     ->  Hash
+                           Output: t1_2.a, t1_2.c, t2_2.b, t2_2.c
+                           ->  Hash Right Join
+                                 Output: t1_2.a, t1_2.c, t2_2.b, t2_2.c
+                                 Hash Cond: ((t2_2.b = t1_2.a) AND (t2_2.c = t1_2.c))
+                                 ->  Seq Scan on public.plt2_p3 t2_2
+                                       Output: t2_2.b, t2_2.c
+                                 ->  Hash
+                                       Output: t1_2.a, t1_2.c
+                                       ->  Seq Scan on public.plt1_p3 t1_2
+                                             Output: t1_2.a, t1_2.c
+                                             Filter: ((t1_2.a % 25) = 0)
+(57 rows)
+
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (plt1 t1 LEFT JOIN plt2 t2 ON t1.a = t2.b AND t1.c = t2.c) LEFT JOIN plt1_e t3 ON (t2.b = t3.a AND t2.c = ltrim(t3.c, 'A')) WHERE t1.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+  a  |  c   |  b  |  c   | ?column? |   c   
+-----+------+-----+------+----------+-------
+   0 | 0000 |   0 | 0000 |        0 | A0000
+  50 | 0001 |     |      |          | 
+ 100 | 0002 |     |      |          | 
+ 150 | 0003 | 150 | 0003 |      300 | A0003
+ 200 | 0004 |     |      |          | 
+ 250 | 0005 |     |      |          | 
+ 300 | 0006 | 300 | 0006 |      600 | A0006
+ 350 | 0007 |     |      |          | 
+ 400 | 0008 |     |      |          | 
+ 450 | 0009 | 450 | 0009 |      900 | A0009
+ 500 | 0010 |     |      |          | 
+ 550 | 0011 |     |      |          | 
+(12 rows)
+
 -- joins where one of the relations is proven empty
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2;
@@ -1361,6 +2060,172 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1
                      One-Time Filter: false
 (14 rows)
 
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT sum(t1.a), t1.c, avg(t2.b), t2.c FROM plt1 t1, plt2 t2 WHERE t1.c = t2.c AND t1.c NOT IN ('0001', '0005', '0002', '0009') AND t2.c NOT IN ('0000', '0003', '0004', '0010') GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c;
+                                          QUERY PLAN                                           
+-----------------------------------------------------------------------------------------------
+ Sort
+   Output: (sum(t1.a)), t1.c, (avg(t2.b)), t2.c
+   Sort Key: t1.c
+   ->  HashAggregate
+         Output: sum(t1.a), t1.c, avg(t2.b), t2.c
+         Group Key: t1.c, t2.c
+         ->  Result
+               Output: t1.c, t2.c, t1.a, t2.b
+               ->  Append
+                     ->  Hash Join
+                           Output: t1.a, t1.c, t2.b, t2.c
+                           Hash Cond: (t1.c = t2.c)
+                           ->  Seq Scan on public.plt1_p3 t1
+                                 Output: t1.a, t1.c
+                                 Filter: (t1.c <> ALL ('{0001,0005,0002,0009}'::text[]))
+                           ->  Hash
+                                 Output: t2.b, t2.c
+                                 ->  Seq Scan on public.plt2_p3 t2
+                                       Output: t2.b, t2.c
+                                       Filter: (t2.c <> ALL ('{0000,0003,0004,0010}'::text[]))
+(20 rows)
+
+SELECT sum(t1.a), t1.c, avg(t2.b), t2.c FROM plt1 t1, plt2 t2 WHERE t1.c = t2.c AND t1.c NOT IN ('0001', '0005', '0002', '0009') AND t2.c NOT IN ('0000', '0003', '0004', '0010') GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c;
+  sum   |  c   |         avg          |  c   
+--------+------+----------------------+------
+ 137700 | 0006 | 324.0000000000000000 | 0006
+ 158950 | 0007 | 375.0000000000000000 | 0007
+ 169600 | 0008 | 424.5000000000000000 | 0008
+ 229600 | 0011 | 574.5000000000000000 | 0011
+(4 rows)
+
+-- test merge join with index scan
+CREATE INDEX iplt1_p1_c on plt1_p1(c);
+CREATE INDEX iplt1_p2_c on plt1_p2(c);
+CREATE INDEX iplt1_p3_c on plt1_p3(c);
+CREATE INDEX iplt2_p1_c on plt2_p1(c);
+CREATE INDEX iplt2_p2_c on plt2_p2(c);
+CREATE INDEX iplt2_p3_c on plt2_p3(c);
+CREATE INDEX iplt1_e_p1_c on plt1_e_p1(ltrim(c, 'A'));
+CREATE INDEX iplt1_e_p2_c on plt1_e_p2(ltrim(c, 'A'));
+CREATE INDEX iplt1_e_p3_c on plt1_e_p3(ltrim(c, 'A'));
+ANALYZE plt1;
+ANALYZE plt2;
+ANALYZE plt1_e;
+SET enable_hashjoin TO off;
+SET enable_nestloop TO off;
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM ((SELECT * FROM plt1 WHERE plt1.a % 25 = 0) t1 FULL JOIN (SELECT * FROM plt2 WHERE plt2.b % 25 = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c)) FULL JOIN (SELECT * FROM plt1_e WHERE plt1_e.a % 25 = 0) t3 ON (t1.a = t3.a AND ltrim(t3.c, 'A') = t1.c) ORDER BY t1.a, t2.b, t3.a + t3.b;
+                                                  QUERY PLAN                                                   
+---------------------------------------------------------------------------------------------------------------
+ Sort
+   Output: plt1_p1.a, plt1_p1.c, plt2_p1.b, plt2_p1.c, ((plt1_e_p1.a + plt1_e_p1.b)), plt1_e_p1.c
+   Sort Key: plt1_p1.a, plt2_p1.b, ((plt1_e_p1.a + plt1_e_p1.b))
+   ->  Result
+         Output: plt1_p1.a, plt1_p1.c, plt2_p1.b, plt2_p1.c, (plt1_e_p1.a + plt1_e_p1.b), plt1_e_p1.c
+         ->  Append
+               ->  Merge Full Join
+                     Output: plt1_p1.a, plt1_p1.c, plt2_p1.b, plt2_p1.c, plt1_e_p1.a, plt1_e_p1.b, plt1_e_p1.c
+                     Merge Cond: ((plt1_p1.a = plt1_e_p1.a) AND (plt1_p1.c = (ltrim(plt1_e_p1.c, 'A'::text))))
+                     ->  Sort
+                           Output: plt1_p1.a, plt1_p1.c, plt2_p1.b, plt2_p1.c
+                           Sort Key: plt1_p1.a, plt1_p1.c
+                           ->  Merge Full Join
+                                 Output: plt1_p1.a, plt1_p1.c, plt2_p1.b, plt2_p1.c
+                                 Merge Cond: ((plt1_p1.a = plt2_p1.b) AND (plt1_p1.c = plt2_p1.c))
+                                 ->  Sort
+                                       Output: plt1_p1.a, plt1_p1.c
+                                       Sort Key: plt1_p1.a, plt1_p1.c
+                                       ->  Seq Scan on public.plt1_p1
+                                             Output: plt1_p1.a, plt1_p1.c
+                                             Filter: ((plt1_p1.a % 25) = 0)
+                                 ->  Sort
+                                       Output: plt2_p1.b, plt2_p1.c
+                                       Sort Key: plt2_p1.b, plt2_p1.c
+                                       ->  Seq Scan on public.plt2_p1
+                                             Output: plt2_p1.b, plt2_p1.c
+                                             Filter: ((plt2_p1.b % 25) = 0)
+                     ->  Sort
+                           Output: plt1_e_p1.a, plt1_e_p1.b, plt1_e_p1.c, (ltrim(plt1_e_p1.c, 'A'::text))
+                           Sort Key: plt1_e_p1.a, (ltrim(plt1_e_p1.c, 'A'::text))
+                           ->  Seq Scan on public.plt1_e_p1
+                                 Output: plt1_e_p1.a, plt1_e_p1.b, plt1_e_p1.c, ltrim(plt1_e_p1.c, 'A'::text)
+                                 Filter: ((plt1_e_p1.a % 25) = 0)
+               ->  Merge Full Join
+                     Output: plt1_p2.a, plt1_p2.c, plt2_p2.b, plt2_p2.c, plt1_e_p2.a, plt1_e_p2.b, plt1_e_p2.c
+                     Merge Cond: ((plt1_p2.a = plt1_e_p2.a) AND (plt1_p2.c = (ltrim(plt1_e_p2.c, 'A'::text))))
+                     ->  Sort
+                           Output: plt1_p2.a, plt1_p2.c, plt2_p2.b, plt2_p2.c
+                           Sort Key: plt1_p2.a, plt1_p2.c
+                           ->  Merge Full Join
+                                 Output: plt1_p2.a, plt1_p2.c, plt2_p2.b, plt2_p2.c
+                                 Merge Cond: ((plt1_p2.a = plt2_p2.b) AND (plt1_p2.c = plt2_p2.c))
+                                 ->  Sort
+                                       Output: plt1_p2.a, plt1_p2.c
+                                       Sort Key: plt1_p2.a, plt1_p2.c
+                                       ->  Seq Scan on public.plt1_p2
+                                             Output: plt1_p2.a, plt1_p2.c
+                                             Filter: ((plt1_p2.a % 25) = 0)
+                                 ->  Sort
+                                       Output: plt2_p2.b, plt2_p2.c
+                                       Sort Key: plt2_p2.b, plt2_p2.c
+                                       ->  Seq Scan on public.plt2_p2
+                                             Output: plt2_p2.b, plt2_p2.c
+                                             Filter: ((plt2_p2.b % 25) = 0)
+                     ->  Sort
+                           Output: plt1_e_p2.a, plt1_e_p2.b, plt1_e_p2.c, (ltrim(plt1_e_p2.c, 'A'::text))
+                           Sort Key: plt1_e_p2.a, (ltrim(plt1_e_p2.c, 'A'::text))
+                           ->  Seq Scan on public.plt1_e_p2
+                                 Output: plt1_e_p2.a, plt1_e_p2.b, plt1_e_p2.c, ltrim(plt1_e_p2.c, 'A'::text)
+                                 Filter: ((plt1_e_p2.a % 25) = 0)
+               ->  Merge Full Join
+                     Output: plt1_p3.a, plt1_p3.c, plt2_p3.b, plt2_p3.c, plt1_e_p3.a, plt1_e_p3.b, plt1_e_p3.c
+                     Merge Cond: ((plt1_p3.a = plt1_e_p3.a) AND (plt1_p3.c = (ltrim(plt1_e_p3.c, 'A'::text))))
+                     ->  Sort
+                           Output: plt1_p3.a, plt1_p3.c, plt2_p3.b, plt2_p3.c
+                           Sort Key: plt1_p3.a, plt1_p3.c
+                           ->  Merge Full Join
+                                 Output: plt1_p3.a, plt1_p3.c, plt2_p3.b, plt2_p3.c
+                                 Merge Cond: ((plt1_p3.a = plt2_p3.b) AND (plt1_p3.c = plt2_p3.c))
+                                 ->  Sort
+                                       Output: plt1_p3.a, plt1_p3.c
+                                       Sort Key: plt1_p3.a, plt1_p3.c
+                                       ->  Seq Scan on public.plt1_p3
+                                             Output: plt1_p3.a, plt1_p3.c
+                                             Filter: ((plt1_p3.a % 25) = 0)
+                                 ->  Sort
+                                       Output: plt2_p3.b, plt2_p3.c
+                                       Sort Key: plt2_p3.b, plt2_p3.c
+                                       ->  Seq Scan on public.plt2_p3
+                                             Output: plt2_p3.b, plt2_p3.c
+                                             Filter: ((plt2_p3.b % 25) = 0)
+                     ->  Sort
+                           Output: plt1_e_p3.a, plt1_e_p3.b, plt1_e_p3.c, (ltrim(plt1_e_p3.c, 'A'::text))
+                           Sort Key: plt1_e_p3.a, (ltrim(plt1_e_p3.c, 'A'::text))
+                           ->  Seq Scan on public.plt1_e_p3
+                                 Output: plt1_e_p3.a, plt1_e_p3.b, plt1_e_p3.c, ltrim(plt1_e_p3.c, 'A'::text)
+                                 Filter: ((plt1_e_p3.a % 25) = 0)
+(87 rows)
+
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM ((SELECT * FROM plt1 WHERE plt1.a % 25 = 0) t1 FULL JOIN (SELECT * FROM plt2 WHERE plt2.b % 25 = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c)) FULL JOIN (SELECT * FROM plt1_e WHERE plt1_e.a % 25 = 0) t3 ON (t1.a = t3.a AND ltrim(t3.c, 'A') = t1.c) ORDER BY t1.a, t2.b, t3.a + t3.b;
+  a  |  c   |  b  |  c   | ?column? |   c   
+-----+------+-----+------+----------+-------
+   0 | 0000 |   0 | 0000 |        0 | A0000
+  50 | 0001 |     |      |      100 | A0001
+ 100 | 0002 |     |      |      200 | A0002
+ 150 | 0003 | 150 | 0003 |      300 | A0003
+ 200 | 0004 |     |      |      400 | A0004
+ 250 | 0005 |     |      |      500 | A0005
+ 300 | 0006 | 300 | 0006 |      600 | A0006
+ 350 | 0007 |     |      |      700 | A0007
+ 400 | 0008 |     |      |      800 | A0008
+ 450 | 0009 | 450 | 0009 |      900 | A0009
+ 500 | 0010 |     |      |     1000 | A0010
+ 550 | 0011 |     |      |     1100 | A0011
+     |      |  75 | 0001 |          | 
+     |      | 225 | 0004 |          | 
+     |      | 375 | 0007 |          | 
+     |      | 525 | 0010 |          | 
+(16 rows)
+
+RESET enable_hashjoin;
+RESET enable_nestloop;
 --
 -- multi-leveled partitions
 --
@@ -1687,6 +2552,42 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2)
                One-Time Filter: false
 (11 rows)
 
+-- Join with pruned partitions from joining relations
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c AND t1.b + t1.a = t2.a + t2.b AND t1.a < 450 AND t2.b > 250 AND t1.a % 25 = 0 ORDER BY t1.a, t2.b;
+                                                            QUERY PLAN                                                            
+----------------------------------------------------------------------------------------------------------------------------------
+ Sort
+   Output: t1.a, t1.c, t2.b, t2.c
+   Sort Key: t1.a
+   ->  Append
+         ->  Hash Join
+               Output: t1.a, t1.c, t2.b, t2.c
+               Hash Cond: ((t2.b = t1.a) AND (t2.a = t1.b) AND ((t2.c)::text = (t1.c)::text) AND ((t2.a + t2.b) = (t1.b + t1.a)))
+               ->  Append
+                     ->  Seq Scan on public.prt2_l_p2_p1 t2
+                           Output: t2.b, t2.c, t2.a
+                           Filter: (t2.b > 250)
+                     ->  Seq Scan on public.prt2_l_p2_p2 t2_1
+                           Output: t2_1.b, t2_1.c, t2_1.a
+                           Filter: (t2_1.b > 250)
+               ->  Hash
+                     Output: t1.a, t1.c, t1.b
+                     ->  Append
+                           ->  Seq Scan on public.prt1_l_p2_p1 t1
+                                 Output: t1.a, t1.c, t1.b
+                                 Filter: ((t1.a < 450) AND ((t1.a % 25) = 0))
+                           ->  Seq Scan on public.prt1_l_p2_p2 t1_1
+                                 Output: t1_1.a, t1_1.c, t1_1.b
+                                 Filter: ((t1_1.a < 450) AND ((t1_1.a % 25) = 0))
+(23 rows)
+
+SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c AND t1.b + t1.a = t2.a + t2.b AND t1.a < 450 AND t2.b > 250 AND t1.a % 25 = 0 ORDER BY t1.a, t2.b;
+  a  |  c   |  b  |  c   
+-----+------+-----+------
+ 300 | 0000 | 300 | 0000
+(1 row)
+
 --
 -- negative testcases
 --
diff --git a/src/test/regress/sql/partition_join.sql b/src/test/regress/sql/partition_join.sql
index 21734f5..d8f818a 100644
--- a/src/test/regress/sql/partition_join.sql
+++ b/src/test/regress/sql/partition_join.sql
@@ -99,6 +99,27 @@ SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL
 			  (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
 			  ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a;
 
+-- join with aggregate
+EXPLAIN (VERBOSE, COSTS OFF)
+select t1.a, count(t2.*) from prt1 t1 left join prt1 t2 on (t1.a = t2.a) where t1.a % 25 = 0 group by t1.a;
+select t1.a, count(t2.*) from prt1 t1 left join prt1 t2 on (t1.a = t2.a) where t1.a % 25 = 0 group by t1.a;
+
+-- lateral with VALUES
+EXPLAIN (VERBOSE, COSTS OFF)
+select count(*) from prt1 a, prt2 b join lateral (values(a.a)) ss(x) on b.b = ss.x;
+select count(*) from prt1 a, prt2 b join lateral (values(a.a)) ss(x) on b.b = ss.x;
+
+-- join with rank
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.b, t2.b,rank() OVER (ORDER BY t2.b DESC) FROM prt1 t1 inner join prt2 t2 on (t1.a = t2.b) where t1.a % 25 = 0 order by 1,2,3;
+SELECT t1.a, t1.b, t2.b,rank() OVER (ORDER BY t2.b DESC) FROM prt1 t1 inner join prt2 t2 on (t1.a = t2.b) where t1.a % 25 = 0 order by 1,2,3;
+
+--join with prepare statement
+PREPARE ij(int) AS select t1.a,t2.b from prt1 t1 inner join prt2 t2 on (t1.a = t2.b and t1.a % $1 = 0) ORDER BY 1,2;
+EXPLAIN (VERBOSE, COSTS OFF) EXECUTE ij(25);
+EXECUTE ij(25);
+DEALLOCATE ij;
+
 --
 -- partitioned by expression
 --
@@ -163,7 +184,28 @@ SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (
 
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
-SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a,
+t2.b, t3.a + t3.b;
+
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.a %25 = 0)) AND t1.a % 25 = 0 ORDER BY t1.a;
+SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.a %25 = 0)) AND t1.a % 25 = 0 ORDER BY t1.a;
+
+SET enable_seqscan TO off;
+
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t2.b = (t3.a + t3.b)/2) WHERE t3.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t2.b = (t3.a + t3.b)/2) WHERE t3.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+
+-- lateral references and parameterized paths
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM prt1 t1 LEFT JOIN LATERAL
+(SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
+ON t1.a = ss.t2a WHERE t1.a % 25 = 0 ORDER BY t1.a;
+SELECT * FROM prt1 t1 LEFT JOIN LATERAL
+(SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
+ON t1.a = ss.t2a WHERE t1.a % 25 = 0 ORDER BY t1.a;
+RESET enable_seqscan;
 
 -- MergeAppend on nullable column
 EXPLAIN (COSTS OFF)
@@ -211,6 +253,20 @@ CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0
 INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i;
 ANALYZE plt2;
 
+--full join using
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM plt1 t1 FULL JOIN plt2 t2 USING (c) FULL JOIN plt1 t3 USING (c)
+where t1.a %150 =0 and t2.b % 150 = 0 and t3.a % 150 = 0 order by 1,2,3;
+SELECT * FROM plt1 t1 FULL JOIN plt2 t2 USING (c) FULL JOIN plt1 t3 USING (c)
+where t1.a %150 =0 and t2.b % 150 = 0 and t3.a % 150 = 0 order by 1,2,3;
+
+-- test placement of movable quals in a parameterized join tree
+EXPLAIN (VERBOSE, COSTS OFF)
+select b.b from prt1 a join prt2 b on a.a = b.b left join plt1 c on b.a % 25 = 0 and c.c = a.c join prt1 i1 on b.b = i1.a
+right join prt2 i2 on i2.b = b.b where b.a % 25 = 0 order by 1;
+select b.b from prt1 a join prt2 b on a.a = b.b left join plt1 c on b.a % 25 = 0 and c.c = a.c join prt1 i1 on b.b = i1.a
+right join prt2 i2 on i2.b = b.b where b.a % 25 = 0 order by 1;
+
 --
 -- list partitioned by expression
 --
@@ -226,6 +282,10 @@ EXPLAIN (COSTS OFF)
 SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c;
 SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c;
 
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (plt1 t1 LEFT JOIN plt2 t2 ON t1.a = t2.b AND t1.c = t2.c) LEFT JOIN plt1_e t3 ON (t2.b = t3.a AND t2.c = ltrim(t3.c, 'A')) WHERE t1.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (plt1 t1 LEFT JOIN plt2 t2 ON t1.a = t2.b AND t1.c = t2.c) LEFT JOIN plt1_e t3 ON (t2.b = t3.a AND t2.c = ltrim(t3.c, 'A')) WHERE t1.a % 25 = 0 ORDER BY t1.a, t2.b, t3.a + t3.b;
+
 -- joins where one of the relations is proven empty
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2;
@@ -239,6 +299,35 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 FULL JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b;
 
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT sum(t1.a), t1.c, avg(t2.b), t2.c FROM plt1 t1, plt2 t2 WHERE t1.c = t2.c AND t1.c NOT IN ('0001', '0005', '0002', '0009') AND t2.c NOT IN ('0000', '0003', '0004', '0010') GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c;
+SELECT sum(t1.a), t1.c, avg(t2.b), t2.c FROM plt1 t1, plt2 t2 WHERE t1.c = t2.c AND t1.c NOT IN ('0001', '0005', '0002', '0009') AND t2.c NOT IN ('0000', '0003', '0004', '0010') GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c;
+
+-- test merge join with index scan
+CREATE INDEX iplt1_p1_c on plt1_p1(c);
+CREATE INDEX iplt1_p2_c on plt1_p2(c);
+CREATE INDEX iplt1_p3_c on plt1_p3(c);
+CREATE INDEX iplt2_p1_c on plt2_p1(c);
+CREATE INDEX iplt2_p2_c on plt2_p2(c);
+CREATE INDEX iplt2_p3_c on plt2_p3(c);
+CREATE INDEX iplt1_e_p1_c on plt1_e_p1(ltrim(c, 'A'));
+CREATE INDEX iplt1_e_p2_c on plt1_e_p2(ltrim(c, 'A'));
+CREATE INDEX iplt1_e_p3_c on plt1_e_p3(ltrim(c, 'A'));
+
+ANALYZE plt1;
+ANALYZE plt2;
+ANALYZE plt1_e;
+
+SET enable_hashjoin TO off;
+SET enable_nestloop TO off;
+
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM ((SELECT * FROM plt1 WHERE plt1.a % 25 = 0) t1 FULL JOIN (SELECT * FROM plt2 WHERE plt2.b % 25 = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c)) FULL JOIN (SELECT * FROM plt1_e WHERE plt1_e.a % 25 = 0) t3 ON (t1.a = t3.a AND ltrim(t3.c, 'A') = t1.c) ORDER BY t1.a, t2.b, t3.a + t3.b;
+SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM ((SELECT * FROM plt1 WHERE plt1.a % 25 = 0) t1 FULL JOIN (SELECT * FROM plt2 WHERE plt2.b % 25 = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c)) FULL JOIN (SELECT * FROM plt1_e WHERE plt1_e.a % 25 = 0) t3 ON (t1.a = t3.a AND ltrim(t3.c, 'A') = t1.c) ORDER BY t1.a, t2.b, t3.a + t3.b;
+
+RESET enable_hashjoin;
+RESET enable_nestloop;
+
 --
 -- multi-leveled partitions
 --
@@ -297,6 +386,11 @@ SELECT * FROM prt1_l t1 LEFT JOIN LATERAL
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c;
 
+-- Join with pruned partitions from joining relations
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c AND t1.b + t1.a = t2.a + t2.b AND t1.a < 450 AND t2.b > 250 AND t1.a % 25 = 0 ORDER BY t1.a, t2.b;
+SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c AND t1.b + t1.a = t2.a + t2.b AND t1.a < 450 AND t2.b > 250 AND t1.a % 25 = 0 ORDER BY t1.a, t2.b;
+
 --
 -- negative testcases
 --
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to