@@ -121,10 +121,12 @@ static void match_restriction_clauses_to_index(RelOptInfo *rel,
121
121
IndexClauseSet * clauseset );
122
122
static void match_join_clauses_to_index (PlannerInfo * root ,
123
123
RelOptInfo * rel , IndexOptInfo * index ,
124
+ Relids lateral_referencers ,
124
125
IndexClauseSet * clauseset ,
125
126
List * * joinorclauses );
126
127
static void match_eclass_clauses_to_index (PlannerInfo * root ,
127
128
IndexOptInfo * index ,
129
+ Relids lateral_referencers ,
128
130
IndexClauseSet * clauseset );
129
131
static void match_clauses_to_index (IndexOptInfo * index ,
130
132
List * clauses ,
@@ -211,22 +213,40 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
211
213
List * bitindexpaths ;
212
214
List * bitjoinpaths ;
213
215
List * joinorclauses ;
216
+ Relids lateral_referencers ;
214
217
IndexClauseSet rclauseset ;
215
218
IndexClauseSet jclauseset ;
216
219
IndexClauseSet eclauseset ;
217
- ListCell * ilist ;
220
+ ListCell * lc ;
218
221
219
222
/* Skip the whole mess if no indexes */
220
223
if (rel -> indexlist == NIL )
221
224
return ;
222
225
226
+ /*
227
+ * If there are any rels that have LATERAL references to this one, we
228
+ * cannot use join quals referencing them as index quals for this one,
229
+ * since such rels would have to be on the inside not the outside of a
230
+ * nestloop join relative to this one. Create a Relids set listing all
231
+ * such rels, for use in checks of potential join clauses.
232
+ */
233
+ lateral_referencers = NULL ;
234
+ foreach (lc , root -> lateral_info_list )
235
+ {
236
+ LateralJoinInfo * ljinfo = (LateralJoinInfo * ) lfirst (lc );
237
+
238
+ if (bms_is_member (rel -> relid , ljinfo -> lateral_lhs ))
239
+ lateral_referencers = bms_add_member (lateral_referencers ,
240
+ ljinfo -> lateral_rhs );
241
+ }
242
+
223
243
/* Bitmap paths are collected and then dealt with at the end */
224
244
bitindexpaths = bitjoinpaths = joinorclauses = NIL ;
225
245
226
246
/* Examine each index in turn */
227
- foreach (ilist , rel -> indexlist )
247
+ foreach (lc , rel -> indexlist )
228
248
{
229
- IndexOptInfo * index = (IndexOptInfo * ) lfirst (ilist );
249
+ IndexOptInfo * index = (IndexOptInfo * ) lfirst (lc );
230
250
231
251
/* Protect limited-size array in IndexClauseSets */
232
252
Assert (index -> ncolumns <= INDEX_MAX_KEYS );
@@ -260,15 +280,16 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
260
280
* EquivalenceClasses. Also, collect join OR clauses for later.
261
281
*/
262
282
MemSet (& jclauseset , 0 , sizeof (jclauseset ));
263
- match_join_clauses_to_index (root , rel , index ,
283
+ match_join_clauses_to_index (root , rel , index , lateral_referencers ,
264
284
& jclauseset , & joinorclauses );
265
285
266
286
/*
267
287
* Look for EquivalenceClasses that can generate joinclauses matching
268
288
* the index.
269
289
*/
270
290
MemSet (& eclauseset , 0 , sizeof (eclauseset ));
271
- match_eclass_clauses_to_index (root , index , & eclauseset );
291
+ match_eclass_clauses_to_index (root , index , lateral_referencers ,
292
+ & eclauseset );
272
293
273
294
/*
274
295
* If we found any plain or eclass join clauses, decide what to do
@@ -1796,6 +1817,7 @@ match_restriction_clauses_to_index(RelOptInfo *rel, IndexOptInfo *index,
1796
1817
static void
1797
1818
match_join_clauses_to_index (PlannerInfo * root ,
1798
1819
RelOptInfo * rel , IndexOptInfo * index ,
1820
+ Relids lateral_referencers ,
1799
1821
IndexClauseSet * clauseset ,
1800
1822
List * * joinorclauses )
1801
1823
{
@@ -1810,6 +1832,10 @@ match_join_clauses_to_index(PlannerInfo *root,
1810
1832
if (!join_clause_is_movable_to (rinfo , rel -> relid ))
1811
1833
continue ;
1812
1834
1835
+ /* Not useful if it conflicts with any LATERAL references */
1836
+ if (bms_overlap (rinfo -> clause_relids , lateral_referencers ))
1837
+ continue ;
1838
+
1813
1839
/* Potentially usable, so see if it matches the index or is an OR */
1814
1840
if (restriction_is_or_clause (rinfo ))
1815
1841
* joinorclauses = lappend (* joinorclauses , rinfo );
@@ -1825,6 +1851,7 @@ match_join_clauses_to_index(PlannerInfo *root,
1825
1851
*/
1826
1852
static void
1827
1853
match_eclass_clauses_to_index (PlannerInfo * root , IndexOptInfo * index ,
1854
+ Relids lateral_referencers ,
1828
1855
IndexClauseSet * clauseset )
1829
1856
{
1830
1857
int indexcol ;
@@ -1837,9 +1864,11 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
1837
1864
{
1838
1865
List * clauses ;
1839
1866
1867
+ /* Generate clauses, skipping any that join to lateral_referencers */
1840
1868
clauses = generate_implied_equalities_for_indexcol (root ,
1841
1869
index ,
1842
- indexcol );
1870
+ indexcol ,
1871
+ lateral_referencers );
1843
1872
1844
1873
/*
1845
1874
* We have to check whether the results actually do match the index,
0 commit comments