8000 fix custom_scan_tlist generation, improve pick_suitable_index() · postgrespro/pgsphere@3395a25 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3395a25

Browse files
committed
fix custom_scan_tlist generation, improve pick_suitable_index()
1 parent 7bc3591 commit 3395a25

File tree

1 file changed

+40
-54
lines changed

1 file changed

+40
-54
lines changed

init.c

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
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
*/
174175
static Oid
175-
pick_suitable_index(Oid relation, AttrNumber column)
176+
pick_suitable_index(RelOptInfo *relation, AttrNumber column)
176177
{
177178
Oid found_index = InvalidOid;
178179
int64 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 index with no predicates and
210-
* its first column is the required spoint with opclass 'spoint2'.
192+
* check if this is a valid GIST index and 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

218201
if (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;
229207
found_index_size = cur_index_size;
230208
}
231209
}
232210
}
233211
}
234212

235-
systable_endscan(scan);
236-
heap_close(pg_index, AccessShareLock);
237-
238213
return found_index;
239214
}
240215

@@ -301,16 +276,22 @@ create_crossmatch_path(PlannerInfo *root,
301276
{
302277
CrossmatchJoinPath *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)
310291
return;
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
{
315296
return;
316297
}
@@ -328,10 +309,10 @@ create_crossmatch_path(PlannerInfo *root,
328309
result->cpath.methods = &crossmatch_path_methods;
329310
result->outer_path = outer_path;
330311
result->outer_idx = outer_idx;
331-
result->outer_rel = outer_rel;
312+
result->outer_rel = outerrelid;
332313
result->inner_path = inner_path;
333314
result->inner_idx = inner_idx;
334-
result->inner_rel = inner_rel;
315+
result->inner_rel = innerrelid;
335316
result->threshold = threshold;
336317
result->joinrestrictinfo = restrict_clauses;
337318

@@ -468,6 +449,7 @@ create_crossmatch_plan(PlannerInfo *root,
468449
List *joinrestrictclauses = gpath->joinrestrictinfo;
469450
List *joinclauses;
470451
CustomScan *cscan;
452+
PathTarget *target;
471453

472454
Assert(!IS_OUTER_JOIN(gpath->jointype));
473455
joinclauses = extract_actual_clauses(joinrestrictclauses, false);
@@ -477,8 +459,12 @@ create_crossmatch_plan(PlannerInfo *root,
477459
cscan->scan.plan.qual = joinclauses;
478460
cscan->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

483469
cscan->flags = best_path->flags;
484470
cscan->methods = &crossmatch_plan_methods;

0 commit comments

Comments
 (0)
0