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

Skip to content

Commit 934e8d0

Browse files
committed
new macro IsVarSpointDist, create_crossmatch_path() uses actual spoint attnums, fixed threshold save\restore
1 parent 73cc7cc commit 934e8d0

File tree

1 file changed

+91
-35
lines changed

1 file changed

+91
-35
lines changed

init.c

Lines changed: 91 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ static CustomScanMethods crossmatch_plan_methods;
7878
static CustomExecMethods crossmatch_exec_methods;
7979

8080

81+
#define IsVarSpointDist(arg, dist_func_oid) \
82+
( \
83+
IsA(arg, FuncExpr) && \
84+
((FuncExpr *) (arg))->funcid == (dist_func_oid) && \
85+
IsA(linitial(((FuncExpr *) (arg))->args), Var) && \
86+
IsA(lsecond(((FuncExpr *) (arg))->args), Var) \
87+
)
88+
89+
90+
static float8
91+
cstring_to_float8(char *str)
92+
{
93+
return DatumGetFloat8(DirectFunctionCall1(float8in,
94+
CStringGetDatum(str)));
95+
}
96+
97+
static char *
98+
float8_to_cstring(float8 val)
99+
{
100+
return DatumGetCString(DirectFunctionCall1(float8out,
101+
Float8GetDatum(val)));
102+
}
103+
81104
static float8
82105
get_const_val(Const *node)
83106
{
@@ -174,6 +197,26 @@ pick_suitable_index(Oid relation, AttrNumber column)
174197
return found_index;
175198
}
176199

200+
static void
201+
get_spoint_attnums(FuncExpr *fexpr, RelOptInfo *outer, RelOptInfo *inner,
202+
AttrNumber *outer_spoint, AttrNumber *inner_spoint)
203+
{
204+
ListCell *dist_arg;
205+
206+
Assert(outer->relid != 0 && inner->relid != 0);
207+
208+
foreach(dist_arg, fexpr->args)
209+
{
210+
Var *arg = (Var *) lfirst(dist_arg);
211+
212+
if (arg->varno == outer->relid)
213+
*outer_spoint = arg->varoattno;
214+
215+
if (arg->varno == inner->relid)
216+
*inner_spoint = arg->varoattno;
217+
}
218+
}
219+
177220
static Path *
178221
crossmatch_find_cheapest_path(PlannerInfo *root,
179222
RelOptInfo *joinrel,
@@ -211,7 +254,9 @@ create_crossmatch_path(PlannerInfo *root,
211254
ParamPathInfo *param_info,
212255
List *restrict_clauses,
213256
Relids required_outer,
214-
float8 threshold)
257+
float8 threshold,
258+
AttrNumber outer_spoint,
259+
AttrNumber inner_spoint)
215260
{
216261
CrossmatchJoinPath *result;
217262

@@ -221,8 +266,8 @@ create_crossmatch_path(PlannerInfo *root,
221266
Oid inner_idx;
222267

223268
/* TODO: use actual column numbers */
224-
if ((outer_idx = pick_suitable_index(outer_rel, 1)) == InvalidOid ||
225-
(inner_idx = pick_suitable_index(inner_rel, 1)) == InvalidOid)
269+
if ((outer_idx = pick_suitable_index(outer_rel, outer_spoint)) == InvalidOid ||
270+
(inner_idx = pick_suitable_index(inner_rel, inner_spoint)) == InvalidOid)
226271
{
227272
return;
228273
}
@@ -280,7 +325,7 @@ join_pathlist_hook(PlannerInfo *root,
280325
PointerGetDatum(dist_func_name)));
281326

282327
if (dist_func == InvalidOid)
283-
elog(ERROR, "function dist not found!");
328+
return;
284329

285330
if (set_join_pathlist_next)
286331
set_join_pathlist_next(root,
@@ -312,10 +357,11 @@ join_pathlist_hook(PlannerInfo *root,
312357
arg2 = lsecond(opExpr->args);
313358

314359
if (opExpr->opno == Float8LessOperator &&
315-
IsA(arg1, FuncExpr) &&
316-
((FuncExpr *) arg1)->funcid == dist_func &&
317-
IsA(arg2, Const))
360+
IsVarSpointDist(arg1, dist_func) && IsA(arg2, Const))
318361
{
362+
AttrNumber outer_spoint,
363+
inner_spoint;
364+
319365
Path *outer_path = crossmatch_find_cheapest_path(root, joinrel, outerrel);
320366
Path *inner_path = crossmatch_find_cheapest_path(root, joinrel, innerrel);
321367

@@ -329,17 +375,22 @@ join_pathlist_hook(PlannerInfo *root,
329375
required_outer,
330376
&restrict_clauses);
331377

378+
get_spoint_attnums((FuncExpr *) arg1, outerrel, innerrel,
379+
&outer_spoint, &inner_spoint);
380+
332381
create_crossmatch_path(root, joinrel, outer_path, inner_path,
333382
param_info, restrict_clauses, required_outer,
334-
get_const_val((Const *) arg2));
383+
get_const_val((Const *) arg2),
384+
outer_spoint, inner_spoint);
335385

336386
break;
337387
}
338388
else if (opExpr->opno == get_commutator(Float8LessOperator) &&
339-
IsA(arg1, Const) &&
340-
IsA(arg2, FuncExpr) &&
341-
((FuncExpr *) arg2)->funcid == dist_func)
389+
IsA(arg1, Const) && IsVarSpointDist(arg2, dist_func))
342390
{
391+
AttrNumber outer_spoint,
392+
inner_spoint;
393+
343394
/* TODO: merge duplicate code */
344395
Path *outer_path = crossmatch_find_cheapest_path(root, joinrel, outerrel);
345396
Path *inner_path = crossmatch_find_cheapest_path(root, joinrel, innerrel);
@@ -354,9 +405,13 @@ join_pathlist_hook(PlannerInfo *root,
354405
required_outer,
355406
&restrict_clauses);
356407

408+
get_spoint_attnums((FuncExpr *) arg2, outerrel, innerrel,
409+
&outer_spoint, &inner_spoint);
410+
357411
create_crossmatch_path(root, joinrel, outer_path, inner_path,
358412
param_info, restrict_clauses, required_outer,
359-
get_const_val((Const *) arg1));
413+
get_const_val((Const *) arg1),
414+
outer_spoint, inner_spoint);
360415
}
361416
}
362417
}
@@ -372,46 +427,35 @@ create_crossmatch_plan(PlannerInfo *root,
372427
{
373428
CrossmatchJoinPath *gpath = (CrossmatchJoinPath *) best_path;
374429
List *joinrestrictclauses = gpath->joinrestrictinfo;
375-
List *joinclauses; /* NOTE: do we really need it? */
376-
List *otherclauses;
430+
List *joinclauses;
377431
CustomScan *cscan;
378-
float8 *threshold = palloc(sizeof(float8));
379432

380-
if (IS_OUTER_JOIN(gpath->jointype))
381-
{
382-
extract_actual_join_clauses(joinrestrictclauses,
383-
&joinclauses, &otherclauses);
384-
}
385-
else
386-
{
387-
joinclauses = extract_actual_clauses(joinrestrictclauses,
388-
false);
389-
otherclauses = NIL;
390-
}
433+
Assert(!IS_OUTER_JOIN(gpath->jointype));
434+
joinclauses = extract_actual_clauses(joinrestrictclauses, false);
391435

392436
cscan = makeNode(CustomScan);
393437
cscan->scan.plan.targetlist = tlist;
394-
cscan->custom_scan_tlist = tlist; /* output of this node */
395438
cscan->scan.plan.qual = NIL;
396439
cscan->scan.scanrelid = 0;
440+
cscan->custom_scan_tlist = tlist; /* output of this node */
397441

398442
cscan->flags = best_path->flags;
399443
cscan->methods = &crossmatch_plan_methods;
400444

401-
cscan->custom_private = list_make2(list_make4_oid(gpath->outer_idx,
445+
cscan->custom_private = list_make1(list_make4_oid(gpath->outer_idx,
402446
gpath->outer_rel,
403447
gpath->inner_idx,
404-
gpath->inner_rel),
405-
list_make1(threshold));
406-
*threshold = gpath->threshold;
448+
gpath->inner_rel));
449+
cscan->custom_private = lappend(cscan->custom_private,
450+
makeString(float8_to_cstring(gpath->threshold)));
407451

408452
return &cscan->scan.plan;
409453
}
410454

411455
static Node *
412456
crossmatch_create_scan_state(CustomScan *node)
413457
{
414-
CrossmatchScanState *scan_state = palloc0(sizeof(CrossmatchScanState));
458+
CrossmatchScanState *scan_state = palloc0(sizeof(CrossmatchScanState));
415459

416460
NodeSetTag(scan_state, T_CustomScanState);
417461
scan_state->css.flags = node->flags;
@@ -426,7 +470,7 @@ crossmatch_create_scan_state(CustomScan *node)
426470
scan_state->outer_rel = lsecond_oid(linitial(node->custom_private));
427471
scan_state->inner_idx = lthird_oid(linitial(node->custom_private));
428472
scan_state->inner_rel = lfourth_oid(linitial(node->custom_private));
429-
scan_state->threshold = *(float8 *) linitial(lsecond(node->custom_private));
473+
scan_state->threshold = cstring_to_float8(strVal(lsecond(node->custom_private)));
430474

431475
return (Node *) scan_state;
432476
}
@@ -533,8 +577,14 @@ crossmatch_exec(CustomScanState *node)
533577
node->ss.ps.ps_TupFromTlist = false;
534578
}
535579
else
536-
return ExecStoreTuple(htup, node->ss.ps.ps_ResultTupleSlot,
537-
InvalidBuffer, false);
580+
{
581+
TupleTableSlot *result;
582+
583+
result = ExecStoreTuple(htup, node->ss.ps.ps_ResultTupleSlot,
584+
InvalidBuffer, false);
585+
586+
return result;
587+
}
538588
}
539589
}
540590

@@ -572,6 +622,12 @@ crossmatch_explain(CustomScanState *node, List *ancestors, ExplainState *es)
572622
appendStringInfo(&str, "%s",
573623
get_rel_name(scan_state->inner_idx));
574624
ExplainPropertyText("Inner index", str.data, es);
625+
626+
resetStringInfo(&str);
627+
628+
appendStringInfo(&str, "%s",
629+
float8_to_cstring(scan_state->threshold));
630+
ExplainPropertyText("Threshold", str.data, es);
575631
}
576632

577633
void

0 commit comments

Comments
 (0)