33#include "optimizer/pathnode.h"
44#include "optimizer/restrictinfo.h"
55#include "optimizer/tlist.h"
6+ #include "optimizer/var.h"
67#include "utils/tqual.h"
78#include "utils/builtins.h"
89#include "utils/elog.h"
@@ -172,69 +173,43 @@ get_const_val(Const *node)
172173 * whether some partial indices may suffice
173174 */
174175static Oid
175- pick_suitable_index (Oid relation ,AttrNumber column )
176+ pick_suitable_index (RelOptInfo * relation ,AttrNumber column )
176177{
177178Oid found_index = InvalidOid ;
178179int64 found_index_size = 0 ;
179- HeapTuple htup ;
180- SysScanDesc scan ;
181- Relation pg_index ;
182- List * spoint2_opclass_name ;
183- Oid spoint2_opclass ;
184- ScanKeyData key [3 ];
185-
186- spoint2_opclass_name = stringToQualifiedNameList ("public.spoint2" );
187- spoint2_opclass = get_opclass_oid (GIST_AM_OID ,spoint2_opclass_name , false);
188-
189- ScanKeyInit (& key [0 ],
190- Anum_pg_index_indrelid ,
191- BTEqualStrategyNumber ,
192- F_OIDEQ ,
193- ObjectIdGetDatum (relation ));
194-
195- pg_index = heap_open (IndexRelationId ,AccessShareLock );
196- scan = systable_beginscan (pg_index ,InvalidOid , false,NULL ,1 ,key );
197-
198- while (HeapTupleIsValid (htup = systable_getnext (scan )))
199- {
200- Form_pg_index pg_ind = (Form_pg_index )GETSTRUCT (htup );
201- Relation index ;
202- Oid index_am ;
180+ List * spoint2_opfamily_name ;
181+ Oid spoint2_opfamily ;
182+ ListCell * lc ;
183+
184+ spoint2_opfamily_name = stringToQualifiedNameList ("public.spoint2" );
185+ spoint2_opfamily = get_opfamily_oid (GIST_AM_OID ,spoint2_opfamily_name , false);
203186
204- index = index_open ( pg_ind -> indexrelid , AccessShareLock );
205- index_am = index -> rd_rel -> relam ;
206- index_close ( index , AccessShareLock );
187+ foreach ( lc , relation -> indexlist )
188+ {
189+ IndexOptInfo * index = ( IndexOptInfo * ) lfirst ( lc );
207190
208191/*
209- * check if this is a valid GIST indexwith no predicates and
210- *its first column is the required spoint with opclass 'spoint2'.
192+ * check if this is a valid GIST indexand its first
193+ * column is the required spoint with opclass 'spoint2'.
211194 */
212- if (index_am == GIST_AM_OID && pg_ind -> indisvalid &&
213- heap_attisnull ( htup , Anum_pg_index_indpred )&&
214- pg_ind -> indkey . dim1 >=1 && pg_ind -> indkey . values [0 ]== column )
195+ if (index -> relam == GIST_AM_OID &&
196+ ( index -> indpred == NIL || index -> predOK )&&
197+ index -> ncolumns >=1 && index -> indexkeys [0 ]== column )
215198{
216- int64 cur_index_size = get_index_size ( pg_ind -> indexrelid ) ;
199+ int64 cur_index_size = index -> pages ;
217200
218201if (found_index == InvalidOid || cur_index_size < found_index_size )
219202{
220- bool is_null ;
221- Datum indclass = heap_getattr (htup ,Anum_pg_index_indclass ,
222- pg_index -> rd_att ,& is_null );
223- oidvector * indclasses = (oidvector * )DatumGetPointer (indclass );
224-
225203/* column must use 'spoint2' opclass */
226- if (! is_null && indclasses -> values [0 ]== spoint2_opclass )
204+ if (index -> opfamily [0 ]== spoint2_opfamily )
227205{
228- found_index = pg_ind -> indexrelid ;
206+ found_index = index -> indexoid ;
229207found_index_size = cur_index_size ;
230208}
231209}
232210}
233211}
234212
235- systable_endscan (scan );
236- heap_close (pg_index ,AccessShareLock );
237-
238213return found_index ;
239214}
240215
@@ -301,16 +276,22 @@ create_crossmatch_path(PlannerInfo *root,
301276{
302277CrossmatchJoinPath * result ;
303278
304- Oid outer_rel = root -> simple_rte_array [outer_path -> parent -> relid ]-> relid ;
305- Oid inner_rel = root -> simple_rte_array [inner_path -> parent -> relid ]-> relid ;
306- Oid outer_idx ;
307- Oid inner_idx ;
279+ RelOptInfo * outerrel = outer_path -> parent ;
280+ RelOptInfo * innerrel = inner_path -> parent ;
281+ Oid outerrelid = root -> simple_rte_array [outerrel -> relid ]-> relid ;
282+ Oid innerrelid = root -> simple_rte_array [innerrel -> relid ]-> relid ;
283+ Oid outer_idx ;
284+ Oid inner_idx ;
285+
286+ Assert (outerrelid != InvalidOid );
287+ Assert (innerrelid != InvalidOid );
308288
309- if (outer_rel == inner_rel )
289+ /* Relations should be different */
290+ if (outerrel -> relid == innerrel -> relid )
310291return ;
311292
312- if ((outer_idx = pick_suitable_index (outer_rel ,outer_spoint ))== InvalidOid ||
313- (inner_idx = pick_suitable_index (inner_rel ,inner_spoint ))== InvalidOid )
293+ if ((outer_idx = pick_suitable_index (outerrel ,outer_spoint ))== InvalidOid ||
294+ (inner_idx = pick_suitable_index (innerrel ,inner_spoint ))== InvalidOid )
314295{
315296return ;
316297}
@@ -328,10 +309,10 @@ create_crossmatch_path(PlannerInfo *root,
328309result -> cpath .methods = & crossmatch_path_methods ;
329310result -> outer_path = outer_path ;
330311result -> outer_idx = outer_idx ;
331- result -> outer_rel = outer_rel ;
312+ result -> outer_rel = outerrelid ;
332313result -> inner_path = inner_path ;
333314result -> inner_idx = inner_idx ;
334- result -> inner_rel = inner_rel ;
315+ result -> inner_rel = innerrelid ;
335316result -> threshold = threshold ;
336317result -> joinrestrictinfo = restrict_clauses ;
337318
@@ -468,6 +449,7 @@ create_crossmatch_plan(PlannerInfo *root,
468449List * joinrestrictclauses = gpath -> joinrestrictinfo ;
469450List * joinclauses ;
470451CustomScan * cscan ;
452+ PathTarget * target ;
471453
472454Assert (!IS_OUTER_JOIN (gpath -> jointype ));
473455joinclauses = extract_actual_clauses (joinrestrictclauses , false);
@@ -477,8 +459,12 @@ create_crossmatch_plan(PlannerInfo *root,
477459cscan -> scan .plan .qual = joinclauses ;
478460cscan -> scan .scanrelid = 0 ;
479461
462+ /* Add Vars needed for our extended 'joinclauses' */
463+ target = copy_pathtarget (rel -> reltarget );
464+ add_new_columns_to_pathtarget (target ,pull_var_clause ((Node * )joinclauses ,0 ));
465+
480466/* tlist of the 'virtual' join rel we'll have to build and scan */
481- cscan -> custom_scan_tlist = make_tlist_from_pathtarget (rel -> reltarget );
467+ cscan -> custom_scan_tlist = make_tlist_from_pathtarget (target );
482468
483469cscan -> flags = best_path -> flags ;
484470cscan -> methods = & crossmatch_plan_methods ;