Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 723076c

Browse files
committed
refactoring, +pick_suitable_index()
1 parent 9c2fcd0 commit 723076c

File tree

1 file changed

+106
-19
lines changed

1 file changed

+106
-19
lines changed

init.c

Lines changed: 106 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#include "utils/builtins.h"
66
#include "utils/elog.h"
77
#include "utils/lsyscache.h"
8+
#include "utils/rel.h"
9+
#include "utils/fmgroids.h"
810

911
#include "nodes/print.h"
1012

13+
#include "catalog/pg_am.h"
1114
#include "catalog/pg_proc.h"
1215
#include "catalog/pg_operator.h"
1316
#include "commands/explain.h"
@@ -30,7 +33,12 @@ typedef struct
3033
JoinType jointype;
3134

3235
Path *outer_path;
36+
Oid outer_idx;
37+
Oid outer_rel;
38+
3339
Path *inner_path;
40+
Oid inner_idx;
41+
Oid inner_rel;
3442

3543
List *joinrestrictinfo;
3644
} CrossmatchJoinPath;
@@ -41,11 +49,13 @@ typedef struct
4149

4250
List *scan_tlist;
4351

44-
Relation outer_rel;
52+
Oid outer_idx;
53+
Oid outer_rel;
4554
ItemPointer outer_ptr;
4655
HeapTuple outer_tup;
4756

48-
Relation inner_rel;
57+
Oid inner_idx;
58+
Oid inner_rel;
4959
ItemPointer inner_ptr;
5060
HeapTuple inner_tup;
5161
} CrossmatchScanState;
@@ -55,6 +65,71 @@ static CustomScanMethods crossmatch_plan_methods;
5565
static CustomExecMethods crossmatch_exec_methods;
5666

5767

68+
/*
69+
* TODO: check for the predicates & decide
70+
* whether some partial indices may suffice
71+
*/
72+
static Oid
73+
pick_suitable_index(Oid relation, AttrNumber column)
74+
{
75+
Oid found_index = InvalidOid;
76+
int64 found_index_size = 0;
77+
HeapTuple htup;
78+
SysScanDesc scan;
79+
Relation pg_index;
80+
ScanKeyData key[3];
81+
82+
ScanKeyInit(&key[0],
83+
Anum_pg_index_indrelid,
84+
BTEqualStrategyNumber,
85+
F_OIDEQ,
86+
ObjectIdGetDatum(relation));
87+
88+
pg_index = heap_open(IndexRelationId, AccessShareLock);
89+
scan = systable_beginscan(pg_index, InvalidOid, false, NULL, 1, key);
90+
91+
while (HeapTupleIsValid(htup = systable_getnext(scan)))
92+
{
93+
Form_pg_index pg_ind = (Form_pg_index) GETSTRUCT(htup);
94+
Relation index;
95+
Oid index_am;
96+
97+
index = index_open(pg_ind->indexrelid, AccessShareLock);
98+
index_am = index->rd_rel->relam;
99+
index_close(index, AccessShareLock);
100+
101+
/* check if this is a valid GIST index with no predicates */
102+
if (index_am == GIST_AM_OID && pg_ind->indisvalid &&
103+
heap_attisnull(htup, Anum_pg_index_indpred))
104+
{
105+
int i;
106+
107+
for (i = 0; i < pg_ind->indkey.dim1; i++)
108+
{
109+
int64 cur_index_size = 0;
110+
111+
if (pg_ind->indkey.values[i] == column)
112+
{
113+
cur_index_size = DatumGetInt64(
114+
DirectFunctionCall2(pg_relation_size,
115+
ObjectIdGetDatum(relation),
116+
PointerGetDatum(cstring_to_text("main"))));
117+
118+
if (found_index == InvalidOid || cur_index_size < found_index_size)
119+
found_index = pg_ind->indexrelid;
120+
121+
break; /* no need to go further */
122+
}
123+
}
124+
}
125+
}
126+
127+
systable_endscan(scan);
128+
heap_close(pg_index, AccessShareLock);
129+
130+
return found_index;
131+
}
132+
58133
static Path *
59134
crossmatch_find_cheapest_path(PlannerInfo *root,
60135
RelOptInfo *joinrel,
@@ -95,6 +170,18 @@ create_crossmatch_path(PlannerInfo *root,
95170
{
96171
CrossmatchJoinPath *result;
97172

173+
Oid outer_rel = root->simple_rte_array[outer_path->parent->relid]->relid;
174+
Oid inner_rel = root->simple_rte_array[inner_path->parent->relid]->relid;
175+
Oid outer_idx;
176+
Oid inner_idx;
177+
178+
/* TODO: use actual column numbers */
179+
if ((outer_idx = pick_suitable_index(outer_rel, 1)) == InvalidOid ||
180+
(inner_idx = pick_suitable_index(inner_rel, 1)) == InvalidOid)
181+
{
182+
return;
183+
}
184+
98185
result = palloc0(sizeof(CrossmatchJoinPath));
99186
NodeSetTag(result, T_CustomPath);
100187

@@ -107,11 +194,15 @@ create_crossmatch_path(PlannerInfo *root,
107194
result->cpath.flags = 0;
108195
result->cpath.methods = &crossmatch_path_methods;
109196
result->outer_path = outer_path;
197+
result->outer_idx = outer_idx;
198+
result->outer_rel = outer_rel;
110199
result->inner_path = inner_path;
200+
result->inner_idx = inner_idx;
201+
result->inner_rel = inner_rel;
111202
result->joinrestrictinfo = restrict_clauses;
112203

113204
/* TODO: real costs */
114-
result->cpath.path.startup_cost = 1;
205+
result->cpath.path.startup_cost = 0;
115206
result->cpath.path.total_cost = 1;
116207

117208
add_path(joinrel, &result->cpath.path);
@@ -237,12 +328,6 @@ create_crossmatch_plan(PlannerInfo *root,
237328
List *otherclauses;
238329
CustomScan *cscan;
239330

240-
Index lrel = gpath->outer_path->parent->relid;
241-
Index rrel = gpath->inner_path->parent->relid;
242-
243-
/* relids should not be 0 */
244-
Assert(lrel != 0 && rrel != 0);
245-
246331
if (IS_OUTER_JOIN(gpath->jointype))
247332
{
248333
extract_actual_join_clauses(joinrestrictclauses,
@@ -264,8 +349,10 @@ create_crossmatch_plan(PlannerInfo *root,
264349
cscan->flags = best_path->flags;
265350
cscan->methods = &crossmatch_plan_methods;
266351

267-
cscan->custom_private = list_make2_oid(root->simple_rte_array[lrel]->relid,
268-
root->simple_rte_array[rrel]->relid);
352+
cscan->custom_private = list_make4_oid(gpath->outer_idx,
353+
gpath->outer_rel,
354+
gpath->inner_idx,
355+
gpath->inner_rel);
269356

270357
return &cscan->scan.plan;
271358
}
@@ -279,13 +366,15 @@ crossmatch_create_scan_state(CustomScan *node)
279366
scan_state->css.flags = node->flags;
280367
scan_state->css.methods = &crossmatch_exec_methods;
281368

369+
/* TODO: check if this assignment is redundant */
282370
scan_state->css.ss.ps.ps_TupFromTlist = false;
283371

284372
scan_state->scan_tlist = node->custom_scan_tlist;
285-
scan_state->outer_rel = heap_open(linitial_oid(node->custom_private),
286-
AccessShareLock);
287-
scan_state->inner_rel = heap_open(lsecond_oid(node->custom_private),
288-
AccessShareLock);
373+
374+
scan_state->outer_idx = linitial_oid(node->custom_private);
375+
scan_state->outer_rel = lsecond_oid(node->custom_private);
376+
scan_state->inner_idx = lthird_oid(node->custom_private);
377+
scan_state->outer_rel = lfourth_oid(node->custom_private);
289378

290379
return (Node *) scan_state;
291380
}
@@ -306,7 +395,7 @@ crossmatch_exec(CustomScanState *node)
306395

307396
/* TODO: fill with real data from joined tables */
308397
Datum values[2] = { DirectFunctionCall1(spherepoint_in, CStringGetDatum("(0d, 0d)")),
309-
DirectFunctionCall1(spherepoint_in, CStringGetDatum("(0d, 0d)")) };
398+
DirectFunctionCall1(spherepoint_in, CStringGetDatum("(1d, 1d)")) };
310399
bool nulls[2] = {0,0};
311400

312401
elog(LOG, "slot.natts: %d", tupdesc->natts);
@@ -319,6 +408,7 @@ crossmatch_exec(CustomScanState *node)
319408
{
320409
ExprDoneCond isDone;
321410

411+
/* TODO: find a better way to fill 'ecxt_scantuple' */
322412
node->ss.ps.ps_ProjInfo->pi_exprContext->ecxt_scantuple = ExecStoreTuple(htup, slot, InvalidBuffer, false);
323413

324414
result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
@@ -342,10 +432,7 @@ crossmatch_exec(CustomScanState *node)
342432
static void
343433
crossmatch_end(CustomScanState *node)
344434
{
345-
CrossmatchScanState *scan_state = (CrossmatchScanState *) node;
346435

347-
heap_close(scan_state->outer_rel, AccessShareLock);
348-
heap_close(scan_state->inner_rel, AccessShareLock);
349436
}
350437

351438
static void

0 commit comments

Comments
 (0)