@@ -54,7 +54,7 @@ static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey);
54
54
PathKey *
55
55
make_canonical_pathkey (PlannerInfo * root ,
56
56
EquivalenceClass * eclass , Oid opfamily ,
57
- int strategy , bool nulls_first )
57
+ int strategy , bool nulls_first , Expr * src_expr )
58
58
{
59
59
PathKey * pk ;
60
60
ListCell * lc ;
@@ -89,6 +89,7 @@ make_canonical_pathkey(PlannerInfo *root,
89
89
pk -> pk_opfamily = opfamily ;
90
90
pk -> pk_strategy = strategy ;
91
91
pk -> pk_nulls_first = nulls_first ;
92
+ pk -> source_expr = src_expr ;
92
93
93
94
root -> canon_pathkeys = lappend (root -> canon_pathkeys , pk );
94
95
@@ -241,7 +242,7 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
241
242
242
243
/* And finally we can find or create a PathKey node */
243
244
return make_canonical_pathkey (root , eclass , opfamily ,
244
- strategy , nulls_first );
245
+ strategy , nulls_first , expr );
245
246
}
246
247
247
248
/*
@@ -1117,7 +1118,8 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
1117
1118
outer_ec ,
1118
1119
sub_pathkey -> pk_opfamily ,
1119
1120
sub_pathkey -> pk_strategy ,
1120
- sub_pathkey -> pk_nulls_first );
1121
+ sub_pathkey -> pk_nulls_first ,
1122
+ (Expr * ) outer_var );
1121
1123
}
1122
1124
}
1123
1125
else
@@ -1199,7 +1201,8 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
1199
1201
outer_ec ,
1200
1202
sub_pathkey -> pk_opfamily ,
1201
1203
sub_pathkey -> pk_strategy ,
1202
- sub_pathkey -> pk_nulls_first );
1204
+ sub_pathkey -> pk_nulls_first ,
1205
+ (Expr * ) outer_var );
1203
1206
/* score = # of equivalence peers */
1204
1207
score = list_length (outer_ec -> ec_members ) - 1 ;
1205
1208
/* +1 if it matches the proper query_pathkeys item */
@@ -1643,6 +1646,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
1643
1646
List * pathkeys = NIL ;
1644
1647
int nClauses = list_length (mergeclauses );
1645
1648
EquivalenceClass * * ecs ;
1649
+ Expr * * exprs ;
1646
1650
int * scores ;
1647
1651
int necs ;
1648
1652
ListCell * lc ;
@@ -1657,6 +1661,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
1657
1661
* duplicates) and their "popularity" scores.
1658
1662
*/
1659
1663
ecs = (EquivalenceClass * * ) palloc (nClauses * sizeof (EquivalenceClass * ));
1664
+ exprs = (Expr * * ) palloc (nClauses * sizeof (Expr * ));
1660
1665
scores = (int * ) palloc (nClauses * sizeof (int ));
1661
1666
necs = 0 ;
1662
1667
@@ -1666,14 +1671,21 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
1666
1671
EquivalenceClass * oeclass ;
1667
1672
int score ;
1668
1673
ListCell * lc2 ;
1674
+ Expr * expr ;
1669
1675
1670
1676
/* get the outer eclass */
1671
1677
update_mergeclause_eclasses (root , rinfo );
1672
1678
1673
1679
if (rinfo -> outer_is_left )
1680
+ {
1674
1681
oeclass = rinfo -> left_ec ;
1682
+ expr = (Expr * ) linitial (((OpExpr * ) rinfo -> clause )-> args );
1683
+ }
1675
1684
else
1685
+ {
1676
1686
oeclass = rinfo -> right_ec ;
1687
+ expr = (Expr * ) lsecond (((OpExpr * ) rinfo -> clause )-> args );
1688
+ }
1677
1689
1678
1690
/* reject duplicates */
1679
1691
for (j = 0 ; j < necs ; j ++ )
@@ -1697,6 +1709,8 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
1697
1709
}
1698
1710
1699
1711
ecs [necs ] = oeclass ;
1712
+ exprs [necs ] = expr ;
1713
+
1700
1714
scores [necs ] = score ;
1701
1715
necs ++ ;
1702
1716
}
@@ -1798,7 +1812,8 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
1798
1812
ec ,
1799
1813
linitial_oid (ec -> ec_opfamilies ),
1800
1814
BTLessStrategyNumber ,
1801
- false);
1815
+ false,
1816
+ exprs [best_j ]);
1802
1817
/* can't be redundant because no duplicate ECs */
1803
1818
Assert (!pathkey_is_redundant (pathkey , pathkeys ));
1804
1819
pathkeys = lappend (pathkeys , pathkey );
@@ -1852,18 +1867,23 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
1852
1867
EquivalenceClass * oeclass ;
1853
1868
EquivalenceClass * ieclass ;
1854
1869
PathKey * pathkey ;
1870
+ Expr * src_expr ;
1855
1871
1856
1872
update_mergeclause_eclasses (root , rinfo );
1857
1873
1874
+ Assert (IsA (rinfo -> clause , OpExpr ) && rinfo -> orclause == NULL );
1875
+
1858
1876
if (rinfo -> outer_is_left )
1859
1877
{
1860
1878
oeclass = rinfo -> left_ec ;
1861
1879
ieclass = rinfo -> right_ec ;
1880
+ src_expr = (Expr * ) lsecond (((OpExpr * ) rinfo -> clause )-> args );
1862
1881
}
1863
1882
else
1864
1883
{
1865
1884
oeclass = rinfo -> right_ec ;
1866
1885
ieclass = rinfo -> left_ec ;
1886
+ src_expr = (Expr * ) linitial (((OpExpr * ) rinfo -> clause )-> args );
1867
1887
}
1868
1888
1869
1889
/* outer eclass should match current or next pathkeys */
@@ -1891,7 +1911,8 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
1891
1911
ieclass ,
1892
1912
opathkey -> pk_opfamily ,
1893
1913
opathkey -> pk_strategy ,
1894
- opathkey -> pk_nulls_first );
1914
+ opathkey -> pk_nulls_first ,
1915
+ src_expr );
1895
1916
1896
1917
/*
1897
1918
* Don't generate redundant pathkeys (which can happen if multiple
0 commit comments